Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle throw error inside retryTo promise #4377

Merged
merged 12 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ Thanks all to those who are and will have contributing to this awesome project!
<a href="https://github.com/VikalpP"><img src="https://avatars.githubusercontent.com/u/11846339?v=4" title="VikalpP" width="80" height="80"></a>
<a href="https://github.com/elaichenkov"><img src="https://avatars.githubusercontent.com/u/29764053?v=4" title="elaichenkov" width="80" height="80"></a>
<a href="https://github.com/BorisOsipov"><img src="https://avatars.githubusercontent.com/u/6514276?v=4" title="BorisOsipov" width="80" height="80"></a>
<a href="https://github.com/hubidu"><img src="https://avatars.githubusercontent.com/u/13134082?v=4" title="hubidu" width="80" height="80"></a>
<a href="https://github.com/nitschSB"><img src="https://avatars.githubusercontent.com/u/39341455?v=4" title="nitschSB" width="80" height="80"></a>
<a href="https://github.com/hubidu"><img src="https://avatars.githubusercontent.com/u/13134082?v=4" title="hubidu" width="80" height="80"></a>
<a href="https://github.com/jploskonka"><img src="https://avatars.githubusercontent.com/u/669483?v=4" title="jploskonka" width="80" height="80"></a>
<a href="https://github.com/ngraf"><img src="https://avatars.githubusercontent.com/u/7094389?v=4" title="ngraf" width="80" height="80"></a>
<a href="https://github.com/maojunxyz"><img src="https://avatars.githubusercontent.com/u/28778042?v=4" title="maojunxyz" width="80" height="80"></a>
Expand Down
6 changes: 3 additions & 3 deletions docs/helpers/Expect.md → docs/helpers/ExpectHelper.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
permalink: /helpers/Expect
permalink: /helpers/ExpectHelper
editLink: false
sidebar: auto
title: Expect
title: ExpectHelper
---

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
Expand All @@ -20,7 +20,7 @@ Zero-configuration when paired with other helpers like REST, Playwright:
{
helpers: {
Playwright: {...},
Expect: {},
ExpectHelper: {},
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion docs/helpers/Puppeteer.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
26 changes: 18 additions & 8 deletions lib/command/gherkin/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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('--------------------------');
Expand All @@ -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.');
Expand Down
19 changes: 15 additions & 4 deletions lib/command/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion lib/helper/Expect.js → lib/helper/ExpectHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import('chai').then(chai => {
*{
* helpers: {
* Playwright: {...},
* Expect: {},
* ExpectHelper: {},
* }
*}
* ```
Expand Down
2 changes: 1 addition & 1 deletion lib/helper/Playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

/**
Expand Down
6 changes: 3 additions & 3 deletions lib/helper/Puppeteer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

/**
Expand Down Expand Up @@ -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
Expand Down
57 changes: 31 additions & 26 deletions lib/plugin/retryTo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const recorder = require('../recorder');
const store = require('../store');
const { debug } = require('../output');

const defaultConfig = {
Expand Down Expand Up @@ -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;
};
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.Playwright.coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: 'test/acceptance/output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: false,
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.Playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: 'test/acceptance/output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: false,
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.Playwright.retryTo.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: 'test/acceptance/output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: false,
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.Puppeteer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: './output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: false,
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.Testcafe.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports.config = {
url: TestHelper.siteUrl(),
show: true,
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: false,
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.WebDriver.devtools.coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: './output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
mocha: {},
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.WebDriver.devtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: './output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: async () => new Promise(done => {
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/codecept.WebDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports.config = {
require: '../support/ScreenshotSessionHelper.js',
outputPath: './output',
},
Expect: {},
ExpectHelper: {},
},
include: {},
bootstrap: async () => new Promise(done => {
Expand Down
12 changes: 12 additions & 0 deletions test/acceptance/retryTo_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,15 @@ 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);
});

Scenario('Should succeed at the third attempt @plugin', async () => {
await retryTo(async (tryNum) => {
if (tryNum < 2) throw new Error('Custom pluginRetryTo Error');
}, 3);
});
16 changes: 16 additions & 0 deletions test/data/sandbox/configs/gherkin/config_js/codecept.conf.init.js
Original file line number Diff line number Diff line change
@@ -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",
};
Loading
Loading