From e715970c52edad2889e709621ca77e535859baea Mon Sep 17 00:00:00 2001 From: Arthur Stankevich Date: Wed, 29 May 2024 13:54:30 +0200 Subject: [PATCH 01/12] fix(webApi): error message of dontSeeCookie (#4357) * Fixed error message for dontSeeCookie() --- lib/helper/Playwright.js | 2 +- lib/helper/Puppeteer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 697e27561..d03e3af2b 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -1981,7 +1981,7 @@ class Playwright extends Helper { */ async dontSeeCookie(name) { const cookies = await this.browserContext.cookies(); - empty(`cookie ${name} to be set`).assert(cookies.filter(c => c.name === name)); + empty(`cookie ${name} not to be set`).assert(cookies.filter(c => c.name === name)); } /** diff --git a/lib/helper/Puppeteer.js b/lib/helper/Puppeteer.js index 2bb8edac8..874e2ebf7 100644 --- a/lib/helper/Puppeteer.js +++ b/lib/helper/Puppeteer.js @@ -1627,7 +1627,7 @@ class Puppeteer extends Helper { */ async dontSeeCookie(name) { const cookies = await this.page.cookies(); - empty(`cookie ${name} to be set`).assert(cookies.filter(c => c.name === name)); + empty(`cookie ${name} not to be set`).assert(cookies.filter(c => c.name === name)); } /** From 0fb29d7923b82fedcba79e546ab4a51040018a94 Mon Sep 17 00:00:00 2001 From: Ando NARY <36852616+andonary@users.noreply.github.com> Date: Fri, 31 May 2024 06:26:04 +0200 Subject: [PATCH 02/12] fix(cli): gherkin command init with TypeScript (#4366) --- lib/command/gherkin/init.js | 26 ++++-- lib/command/utils.js | 19 +++- .../gherkin/config_js/codecept.conf.init.js | 16 ++++ .../gherkin/config_ts/codecept.conf.init.ts | 15 +++ test/runner/gherkin_test.js | 93 +++++++++++++++++++ 5 files changed, 157 insertions(+), 12 deletions(-) create mode 100644 test/data/sandbox/configs/gherkin/config_js/codecept.conf.init.js create mode 100644 test/data/sandbox/configs/gherkin/config_ts/codecept.conf.init.ts create mode 100644 test/runner/gherkin_test.js diff --git a/lib/command/gherkin/init.js b/lib/command/gherkin/init.js index b0aabe4a8..7ac70231c 100644 --- a/lib/command/gherkin/init.js +++ b/lib/command/gherkin/init.js @@ -4,7 +4,7 @@ const mkdirp = require('mkdirp'); const output = require('../../output'); const { fileExists } = require('../../utils'); const { - getConfig, getTestRoot, updateConfig, safeFileWrite, + getConfig, getTestRoot, updateConfig, safeFileWrite, findConfigFile, } = require('../utils'); const featureFile = `Feature: Business rules @@ -26,7 +26,17 @@ Given('I have a defined step', () => { module.exports = function (genPath) { const testsPath = getTestRoot(genPath); + const configFile = findConfigFile(testsPath); + + if (!configFile) { + output.error( + "Can't initialize Gherkin. This command must be run in an already initialized project." + ); + process.exit(1); + } + const config = getConfig(testsPath); + const extension = path.extname(configFile).substring(1); output.print('Initializing Gherkin (Cucumber BDD) for CodeceptJS'); output.print('--------------------------'); @@ -53,18 +63,18 @@ module.exports = function (genPath) { output.success(`Created ${dir}, place step definitions into it`); } - if (safeFileWrite(path.join(dir, 'steps.js'), stepsFile)) { - output.success('Created sample steps file: step_definitions/steps.js'); + if (safeFileWrite(path.join(dir, `steps.${extension}`), stepsFile)) { + output.success( + `Created sample steps file: step_definitions/steps.${extension}` + ); } config.gherkin = { - features: './features/*.feature', - steps: [ - './step_definitions/steps.js', - ], + features: "./features/*.feature", + steps: [`./step_definitions/steps.${extension}`], }; - updateConfig(testsPath, config); + updateConfig(testsPath, config, extension); output.success('Gherkin setup is done.'); output.success('Start writing feature files and implement corresponding steps.'); diff --git a/lib/command/utils.js b/lib/command/utils.js index ac3cf7fd6..b8c9ca2fa 100644 --- a/lib/command/utils.js +++ b/lib/command/utils.js @@ -41,15 +41,15 @@ function fail(msg) { module.exports.fail = fail; -function updateConfig(testsPath, config, key, extension = 'js') { +function updateConfig(testsPath, config, extension) { const configFile = path.join(testsPath, `codecept.conf.${extension}`); if (!fileExists(configFile)) { - console.log(); const msg = `codecept.conf.${extension} config can\'t be updated automatically`; + console.log(); console.log(`${output.colors.bold.red(msg)}`); - console.log('Please update it manually:'); + console.log(`${output.colors.bold.red("Please update it manually:")}`); console.log(); - console.log(`${key}: ${config[key]}`); + console.log(config); console.log(); return; } @@ -104,3 +104,14 @@ module.exports.createOutputDir = (config, testRoot) => { mkdirp.sync(outputDir); } }; + +module.exports.findConfigFile = (testsPath) => { + const extensions = ['js', 'ts']; + for (const ext of extensions) { + const configFile = path.join(testsPath, `codecept.conf.${ext}`); + if (fileExists(configFile)) { + return configFile; + } + } + return null; +} diff --git a/test/data/sandbox/configs/gherkin/config_js/codecept.conf.init.js b/test/data/sandbox/configs/gherkin/config_js/codecept.conf.init.js new file mode 100644 index 000000000..61e56f1dd --- /dev/null +++ b/test/data/sandbox/configs/gherkin/config_js/codecept.conf.init.js @@ -0,0 +1,16 @@ +/** @type {CodeceptJS.MainConfig} */ +exports.config = { + tests: "./*_test.js", + output: "./output", + helpers: { + Playwright: { + browser: "chromium", + url: "http://localhost", + show: true, + }, + }, + include: { + I: "./steps_file.js", + }, + name: "CodeceptJS", +}; diff --git a/test/data/sandbox/configs/gherkin/config_ts/codecept.conf.init.ts b/test/data/sandbox/configs/gherkin/config_ts/codecept.conf.init.ts new file mode 100644 index 000000000..86fe45f4f --- /dev/null +++ b/test/data/sandbox/configs/gherkin/config_ts/codecept.conf.init.ts @@ -0,0 +1,15 @@ +export const config: CodeceptJS.MainConfig = { + tests: "./*_test.ts", + output: "./output", + helpers: { + Playwright: { + browser: "chromium", + url: "http://localhost", + show: true + } + }, + include: { + I: "./steps_file" + }, + name: "CodeceptJS" +} diff --git a/test/runner/gherkin_test.js b/test/runner/gherkin_test.js new file mode 100644 index 000000000..7a1dbd94a --- /dev/null +++ b/test/runner/gherkin_test.js @@ -0,0 +1,93 @@ +const assert = require("assert"); +const path = require("path"); +const fs = require("fs"); +const exec = require("child_process").exec; + +const runner = path.join(__dirname, "/../../bin/codecept.js"); +const codecept_dir = path.join(__dirname, "/../data/sandbox/configs/gherkin/"); + +describe("gherkin bdd commands", () => { + describe("bdd:init", () => { + let codecept_dir_js = path.join(codecept_dir, "config_js"); + let codecept_dir_ts = path.join(codecept_dir, "config_ts"); + + beforeEach(() => { + fs.copyFileSync( + path.join(codecept_dir_js, "codecept.conf.init.js"), + path.join(codecept_dir_js, "codecept.conf.js") + ); + fs.copyFileSync( + path.join(codecept_dir_ts, "codecept.conf.init.ts"), + path.join(codecept_dir_ts, "codecept.conf.ts") + ); + }); + + afterEach(() => { + try { + fs.rmSync(path.join(codecept_dir_js, "codecept.conf.js")); + fs.rmSync(path.join(codecept_dir_js, "features"), { + recursive: true, + }); + fs.rmSync(path.join(codecept_dir_js, "step_definitions"), { + recursive: true, + }); + } catch (e) {} + try { + fs.rmSync(path.join(codecept_dir_ts, "codecept.conf.ts")); + fs.rmSync(path.join(codecept_dir_ts, "features"), { + recursive: true, + }); + fs.rmSync(path.join(codecept_dir_ts, "step_definitions"), { + recursive: true, + }); + } catch (e) {} + }); + + [ + { + codecept_dir_test: codecept_dir_js, + extension: "js", + }, + { + codecept_dir_test: codecept_dir_ts, + extension: "ts", + }, + ].forEach(({ codecept_dir_test, extension }) => { + it(`prepare CodeceptJS to run feature files (codecept.conf.${extension})`, (done) => { + exec(`${runner} gherkin:init ${codecept_dir_test}`, (err, stdout) => { + let dir = path.join(codecept_dir_test, "features"); + + stdout.should.include( + "Initializing Gherkin (Cucumber BDD) for CodeceptJS" + ); + stdout.should.include( + `Created ${dir}, place your *.feature files in it` + ); + stdout.should.include( + "Created sample feature file: features/basic.feature" + ); + + dir = path.join(codecept_dir_test, "step_definitions"); + stdout.should.include( + `Created ${dir}, place step definitions into it` + ); + stdout.should.include( + `Created sample steps file: step_definitions/steps.${extension}` + ); + assert(!err); + + const configResult = fs + .readFileSync( + path.join(codecept_dir_test, `codecept.conf.${extension}`) + ) + .toString(); + configResult.should.contain(`features: './features/*.feature'`); + configResult.should.contain( + `steps: ['./step_definitions/steps.${extension}']` + ); + done(); + }); + }); + }); + }); +}); From 6566b8c5658800bfbd6730ac3ab3e1d60b08d7d7 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 31 May 2024 04:27:48 +0000 Subject: [PATCH 03/12] DOC: Update contributor faces --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3417207aa..b483e3c80 100644 --- a/README.md +++ b/README.md @@ -315,8 +315,8 @@ Thanks all to those who are and will have contributing to this awesome project! - + From ca956d642495528d1d0ee4310e15d9cac609065b Mon Sep 17 00:00:00 2001 From: KobeN <7845001+kobenguyent@users.noreply.github.com> Date: Sat, 1 Jun 2024 08:07:18 +0200 Subject: [PATCH 04/12] fix(doc): Expect helper is not described correctly (#4370) --- docs/helpers/{Expect.md => ExpectHelper.md} | 6 +++--- lib/helper/{Expect.js => ExpectHelper.js} | 2 +- test/acceptance/codecept.Playwright.coverage.js | 2 +- test/acceptance/codecept.Playwright.js | 2 +- test/acceptance/codecept.Playwright.retryTo.js | 2 +- test/acceptance/codecept.Puppeteer.js | 2 +- test/acceptance/codecept.Testcafe.js | 2 +- test/acceptance/codecept.WebDriver.devtools.coverage.js | 2 +- test/acceptance/codecept.WebDriver.devtools.js | 2 +- test/acceptance/codecept.WebDriver.js | 2 +- test/helper/Expect_test.js | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) rename docs/helpers/{Expect.md => ExpectHelper.md} (98%) rename lib/helper/{Expect.js => ExpectHelper.js} (99%) diff --git a/docs/helpers/Expect.md b/docs/helpers/ExpectHelper.md similarity index 98% rename from docs/helpers/Expect.md rename to docs/helpers/ExpectHelper.md index 4628ea41c..7ffe415ab 100644 --- a/docs/helpers/Expect.md +++ b/docs/helpers/ExpectHelper.md @@ -1,8 +1,8 @@ --- -permalink: /helpers/Expect +permalink: /helpers/ExpectHelper editLink: false sidebar: auto -title: Expect +title: ExpectHelper --- @@ -20,7 +20,7 @@ Zero-configuration when paired with other helpers like REST, Playwright: { helpers: { Playwright: {...}, - Expect: {}, + ExpectHelper: {}, } } ``` diff --git a/lib/helper/Expect.js b/lib/helper/ExpectHelper.js similarity index 99% rename from lib/helper/Expect.js rename to lib/helper/ExpectHelper.js index c9de3693c..c6a9dd27d 100644 --- a/lib/helper/Expect.js +++ b/lib/helper/ExpectHelper.js @@ -23,7 +23,7 @@ import('chai').then(chai => { *{ * helpers: { * Playwright: {...}, - * Expect: {}, + * ExpectHelper: {}, * } *} * ``` diff --git a/test/acceptance/codecept.Playwright.coverage.js b/test/acceptance/codecept.Playwright.coverage.js index f1c57c214..11017f986 100644 --- a/test/acceptance/codecept.Playwright.coverage.js +++ b/test/acceptance/codecept.Playwright.coverage.js @@ -23,7 +23,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: 'test/acceptance/output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: false, diff --git a/test/acceptance/codecept.Playwright.js b/test/acceptance/codecept.Playwright.js index d45a49f50..e4dca9ded 100644 --- a/test/acceptance/codecept.Playwright.js +++ b/test/acceptance/codecept.Playwright.js @@ -23,7 +23,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: 'test/acceptance/output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: false, diff --git a/test/acceptance/codecept.Playwright.retryTo.js b/test/acceptance/codecept.Playwright.retryTo.js index d45a49f50..e4dca9ded 100644 --- a/test/acceptance/codecept.Playwright.retryTo.js +++ b/test/acceptance/codecept.Playwright.retryTo.js @@ -23,7 +23,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: 'test/acceptance/output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: false, diff --git a/test/acceptance/codecept.Puppeteer.js b/test/acceptance/codecept.Puppeteer.js index d18087620..8c2a8e987 100644 --- a/test/acceptance/codecept.Puppeteer.js +++ b/test/acceptance/codecept.Puppeteer.js @@ -19,7 +19,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: './output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: false, diff --git a/test/acceptance/codecept.Testcafe.js b/test/acceptance/codecept.Testcafe.js index 1191bb18a..13b529103 100644 --- a/test/acceptance/codecept.Testcafe.js +++ b/test/acceptance/codecept.Testcafe.js @@ -9,7 +9,7 @@ module.exports.config = { url: TestHelper.siteUrl(), show: true, }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: false, diff --git a/test/acceptance/codecept.WebDriver.devtools.coverage.js b/test/acceptance/codecept.WebDriver.devtools.coverage.js index d4f1089cf..6fb8f5aaa 100644 --- a/test/acceptance/codecept.WebDriver.devtools.coverage.js +++ b/test/acceptance/codecept.WebDriver.devtools.coverage.js @@ -21,7 +21,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: './output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, mocha: {}, diff --git a/test/acceptance/codecept.WebDriver.devtools.js b/test/acceptance/codecept.WebDriver.devtools.js index fc749d22e..f86312789 100644 --- a/test/acceptance/codecept.WebDriver.devtools.js +++ b/test/acceptance/codecept.WebDriver.devtools.js @@ -21,7 +21,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: './output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: async () => new Promise(done => { diff --git a/test/acceptance/codecept.WebDriver.js b/test/acceptance/codecept.WebDriver.js index fd7af8b22..54dd4e3e4 100644 --- a/test/acceptance/codecept.WebDriver.js +++ b/test/acceptance/codecept.WebDriver.js @@ -21,7 +21,7 @@ module.exports.config = { require: '../support/ScreenshotSessionHelper.js', outputPath: './output', }, - Expect: {}, + ExpectHelper: {}, }, include: {}, bootstrap: async () => new Promise(done => { diff --git a/test/helper/Expect_test.js b/test/helper/Expect_test.js index 9567943c0..7db470e01 100644 --- a/test/helper/Expect_test.js +++ b/test/helper/Expect_test.js @@ -5,7 +5,7 @@ import('chai').then(chai => { expect = chai.expect; }); -const ExpectHelper = require('../../lib/helper/Expect'); +const ExpectHelper = require('../../lib/helper/ExpectHelper'); global.codeceptjs = require('../../lib'); From e36d8696012b4db70e5bb8144f556d803b1c436e Mon Sep 17 00:00:00 2001 From: Yoann Fleury Date: Mon, 3 Jun 2024 16:14:40 +0200 Subject: [PATCH 05/12] fix: Puppeteer helper doc typo (#4369) --- docs/helpers/Puppeteer.md | 2 +- lib/helper/Puppeteer.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/helpers/Puppeteer.md b/docs/helpers/Puppeteer.md index 3bf4cf9a0..55fba6b8c 100644 --- a/docs/helpers/Puppeteer.md +++ b/docs/helpers/Puppeteer.md @@ -2476,7 +2476,7 @@ Returns **void** automatically synchronized promise through #recorder [18]: https://codecept.io/helpers/FileSystem -[19]: https://pptr.dev/next/guides/request-interception +[19]: https://pptr.dev/guides/network-interception [20]: https://github.com/GoogleChrome/puppeteer/issues/1313 diff --git a/lib/helper/Puppeteer.js b/lib/helper/Puppeteer.js index 874e2ebf7..2ae747dea 100644 --- a/lib/helper/Puppeteer.js +++ b/lib/helper/Puppeteer.js @@ -2472,12 +2472,12 @@ class Puppeteer extends Helper { } /** - * Mocks network request using [`Request Interception`](https://pptr.dev/next/guides/request-interception) + * Mocks network request using [`Request Interception`](https://pptr.dev/guides/network-interception) * * ```js * I.mockRoute(/(\.png$)|(\.jpg$)/, route => route.abort()); * ``` - * This method allows intercepting and mocking requests & responses. [Learn more about it](https://pptr.dev/next/guides/request-interception) + * This method allows intercepting and mocking requests & responses. [Learn more about it](https://pptr.dev/guides/network-interception) * * @param {string|RegExp} [url] URL, regex or pattern for to match URL * @param {function} [handler] a function to process request From 85adad6318eb51c1196630c0b23eb7ef36524151 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 07:28:49 +0200 Subject: [PATCH 06/12] chore(deps): bump devtools from 8.36.1 to 8.38.0 (#4374) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93eba907c..25ee1a9fe 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "cross-spawn": "7.0.3", "css-to-xpath": "0.1.0", "csstoxpath": "1.6.0", - "devtools": "8.36.1", + "devtools": "8.38.0", "envinfo": "7.11.1", "escape-string-regexp": "4.0.0", "figures": "3.2.0", From e979efd9f8ae1040241f3ce0f97597a50fba5174 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:30:45 +0200 Subject: [PATCH 07/12] chore(deps-dev): bump playwright from 1.44.0 to 1.44.1 (#4376) Bumps [playwright](https://github.com/microsoft/playwright) from 1.44.0 to 1.44.1. - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.44.0...v1.44.1) --- updated-dependencies: - dependency-name: playwright dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 25ee1a9fe..6036024ae 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "jsdoc": "4.0.3", "jsdoc-typeof-plugin": "1.0.0", "json-server": "0.10.1", - "playwright": "1.44.0", + "playwright": "1.44.1", "puppeteer": "22.10.0", "qrcode-terminal": "0.12.0", "rosie": "2.1.1", From 47adee7736cf654ee57cb3424f707a93f813d22d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:44:51 +0200 Subject: [PATCH 08/12] chore(deps): bump axios from 1.6.7 to 1.7.2 (#4372) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6036024ae..772de3097 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@xmldom/xmldom": "0.8.10", "acorn": "8.11.3", "arrify": "2.0.1", - "axios": "1.6.7", + "axios": "1.7.2", "chai": "5.1.1", "chai-deep-match": "1.2.1", "chai-exclude": "2.1.0", From 1af834db504a464ee8ee52d2b4f970b5b58da264 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:45:07 +0200 Subject: [PATCH 09/12] chore(deps-dev): bump typedoc-plugin-markdown from 3.17.1 to 4.0.3 (#4373) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 772de3097..2c56b255b 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "tsd": "^0.31.0", "tsd-jsdoc": "2.5.0", "typedoc": "0.25.13", - "typedoc-plugin-markdown": "3.17.1", + "typedoc-plugin-markdown": "4.0.3", "typescript": "5.3.3", "wdio-docker-service": "1.5.0", "webdriverio": "8.36.1", From 8063ed41f0af25546c3d03ff50ae19e507a67af9 Mon Sep 17 00:00:00 2001 From: Cyril Hue Date: Tue, 4 Jun 2024 17:57:08 +0200 Subject: [PATCH 10/12] fix: handle throw error inside retryTo promise --- lib/plugin/retryTo.js | 57 ++++++++++++++++++--------------- test/acceptance/retryTo_test.js | 6 ++++ test/plugin/plugin_test.js | 13 ++++++++ 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/lib/plugin/retryTo.js b/lib/plugin/retryTo.js index 9929944f1..211b39ac7 100644 --- a/lib/plugin/retryTo.js +++ b/lib/plugin/retryTo.js @@ -1,5 +1,4 @@ const recorder = require('../recorder'); -const store = require('../store'); const { debug } = require('../output'); const defaultConfig = { @@ -73,49 +72,55 @@ const defaultConfig = { * const retryTo = codeceptjs.container.plugins('retryTo'); * ``` * -*/ + */ module.exports = function (config) { config = Object.assign(defaultConfig, config); + function retryTo(callback, maxTries, pollInterval = config.pollInterval) { + return new Promise((done, reject) => { + let tries = 1; - if (config.registerGlobal) { - global.retryTo = retryTo; - } - return retryTo; + function handleRetryException(err) { + recorder.throw(err); + reject(err); + } - function retryTo(callback, maxTries, pollInterval = undefined) { - let tries = 1; - if (!pollInterval) pollInterval = config.pollInterval; - - let err = null; - - return new Promise((done) => { const tryBlock = async () => { + tries++; recorder.session.start(`retryTo ${tries}`); - await callback(tries); + try { + await callback(tries); + } catch (err) { + handleRetryException(err); + } + + // Call done if no errors recorder.add(() => { recorder.session.restore(`retryTo ${tries}`); done(null); }); - recorder.session.catch((e) => { - err = e; + + // Catch errors and retry + recorder.session.catch((err) => { recorder.session.restore(`retryTo ${tries}`); - tries++; if (tries <= maxTries) { debug(`Error ${err}... Retrying`); - err = null; - - recorder.add(`retryTo ${tries}`, () => setTimeout(tryBlock, pollInterval)); + recorder.add(`retryTo ${tries}`, () => + setTimeout(tryBlock, pollInterval) + ); } else { - done(null); + // if maxTries reached + handleRetryException(err); } }); }; - recorder.add('retryTo', async () => { - tryBlock(); - }); - }).then(() => { - if (err) recorder.throw(err); + recorder.add('retryTo', tryBlock); }); } + + if (config.registerGlobal) { + global.retryTo = retryTo; + } + + return retryTo; }; diff --git a/test/acceptance/retryTo_test.js b/test/acceptance/retryTo_test.js index b568e8607..8da0eca31 100644 --- a/test/acceptance/retryTo_test.js +++ b/test/acceptance/retryTo_test.js @@ -14,3 +14,9 @@ Scenario('retryTo works with non await steps @plugin', async () => { if (tryNum < 3) I.waitForVisible('.nothing', 1); }, 4); }); + +Scenario('Should fail after reached max retries', async () => { + await retryTo(() => { + throw new Error('Custom pluginRetryTo Error'); + }, 3); +}); diff --git a/test/plugin/plugin_test.js b/test/plugin/plugin_test.js index 2f615d1d5..1185967b4 100644 --- a/test/plugin/plugin_test.js +++ b/test/plugin/plugin_test.js @@ -61,4 +61,17 @@ describe('CodeceptJS plugin', function () { done(); }); }); + + it('should retry to failure', (done) => { + exec( + `${config_run_config('codecept.Playwright.retryTo.js', 'Should fail after reached max retries')} --verbose`, (err, stdout) => { + const lines = stdout.split('\n'); + expect(lines).toEqual( + expect.arrayContaining([expect.stringContaining('Custom pluginRetryTo Error')]) + ); + expect(err).toBeTruthy(); + done(); + } + ); + }); }); From 312a692f17c98a9e6055786b476cd4d4487f29ba Mon Sep 17 00:00:00 2001 From: Cyril Hue Date: Wed, 5 Jun 2024 11:02:59 +0200 Subject: [PATCH 11/12] fix: test due to update on retryTo plugin --- test/unit/plugin/retryto_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/plugin/retryto_test.js b/test/unit/plugin/retryto_test.js index 28187e02c..6205f347d 100644 --- a/test/unit/plugin/retryto_test.js +++ b/test/unit/plugin/retryto_test.js @@ -20,11 +20,11 @@ describe('retryTo plugin', () => { it('should execute few times command on fail', async () => { let counter = 0; let errorCaught = false; + try { await retryTo(() => { recorder.add(() => counter++); recorder.add(() => { throw new Error('Ups'); }); }, 5, 10); - try { await recorder.promise(); } catch (err) { errorCaught = true; From f71828d6b7d0d3e8dc3193e16f73c45aa224bb0c Mon Sep 17 00:00:00 2001 From: Cyril Hue Date: Wed, 5 Jun 2024 11:09:25 +0200 Subject: [PATCH 12/12] fix: add a test case succeed after 2 retry --- test/acceptance/retryTo_test.js | 6 ++++++ test/unit/plugin/retryto_test.js | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/acceptance/retryTo_test.js b/test/acceptance/retryTo_test.js index 8da0eca31..9d0e1f631 100644 --- a/test/acceptance/retryTo_test.js +++ b/test/acceptance/retryTo_test.js @@ -20,3 +20,9 @@ Scenario('Should fail after reached max retries', async () => { throw new Error('Custom pluginRetryTo Error'); }, 3); }); + +Scenario('Should succeed at the third attempt @plugin', async () => { + await retryTo(async (tryNum) => { + if (tryNum < 2) throw new Error('Custom pluginRetryTo Error'); + }, 3); +}); \ No newline at end of file diff --git a/test/unit/plugin/retryto_test.js b/test/unit/plugin/retryto_test.js index 6205f347d..293adf1d7 100644 --- a/test/unit/plugin/retryto_test.js +++ b/test/unit/plugin/retryto_test.js @@ -21,10 +21,10 @@ describe('retryTo plugin', () => { let counter = 0; let errorCaught = false; try { - await retryTo(() => { - recorder.add(() => counter++); - recorder.add(() => { throw new Error('Ups'); }); - }, 5, 10); + await retryTo(() => { + recorder.add(() => counter++); + recorder.add(() => { throw new Error('Ups'); }); + }, 5, 10); await recorder.promise(); } catch (err) { errorCaught = true;