From 9322fae476f19bcaa03a73dd56386cd94d5ac088 Mon Sep 17 00:00:00 2001 From: thomashohn Date: Fri, 15 Nov 2024 14:46:21 +0100 Subject: [PATCH] Bump eslint from v8 to v9 (#4592) * Bump eslint from v8 to v9 * Possible fix * fix: failed typing tests --------- Co-authored-by: kobenguyent --- .eslintrc.js | 63 ----- .github/dependabot.yml | 3 - docs/helpers/Appium.md | 4 - docs/plugins.md | 239 +++++++++--------- eslint.config.mjs | 81 ++++++ examples/fragments/Signin.js | 1 - examples/pages/Admin.js | 1 - lib/command/gherkin/snippets.js | 2 +- lib/command/workers/runTests.js | 3 +- lib/heal.js | 2 +- lib/helper/Appium.js | 9 +- lib/helper/Nightmare.js | 7 +- lib/helper/Playwright.js | 7 +- lib/helper/Protractor.js | 12 +- lib/helper/Puppeteer.js | 5 +- lib/helper/TestCafe.js | 4 +- lib/helper/WebDriver.js | 23 +- lib/helper/extras/PlaywrightPropEngine.js | 4 +- lib/helper/network/utils.js | 2 +- lib/helper/testcafe/testcafe-utils.js | 2 +- lib/output.js | 6 +- lib/pause.js | 10 +- lib/secret.js | 1 - lib/step.js | 2 +- lib/workers.js | 1 - package.json | 7 +- .../configs/commentStep/customHelper.js | 1 - .../configs/testArtifacts/customHelper.js | 1 - .../step_definitions/my_other_steps.js | 2 +- test/data/sandbox/support/failureHelper.js | 1 - .../sandbox/testscenario_test.testscenario.js | 1 - test/unit/parser_test.js | 1 - test/unit/utils_test.js | 3 +- 33 files changed, 244 insertions(+), 267 deletions(-) delete mode 100644 .eslintrc.js create mode 100644 eslint.config.mjs diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index b38236895..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,63 +0,0 @@ -module.exports = { - extends: 'airbnb-base', - env: { - node: true, - }, - parserOptions: { - ecmaVersion: 2020, - }, - rules: { - 'func-names': 0, - 'no-use-before-define': 0, - 'no-unused-vars': 0, - 'no-underscore-dangle': 0, - 'no-undef': 0, - 'prefer-destructuring': 0, - 'no-param-reassign': 0, - 'max-len': 0, - camelcase: 0, - 'no-shadow': 0, - 'consistent-return': 0, - 'no-console': 0, - 'global-require': 0, - 'class-methods-use-this': 0, - 'no-plusplus': 0, - 'no-return-assign': 0, - 'prefer-rest-params': 0, - 'no-useless-escape': 0, - 'no-restricted-syntax': 0, - 'no-unused-expressions': 0, - 'guard-for-in': 0, - 'no-multi-assign': 0, - 'require-yield': 0, - 'prefer-spread': 0, - 'import/no-dynamic-require': 0, - 'no-continue': 0, - 'no-mixed-operators': 0, - 'default-case': 0, - 'import/no-extraneous-dependencies': 0, - 'no-cond-assign': 0, - 'import/no-unresolved': 0, - 'no-await-in-loop': 0, - 'arrow-body-style': 0, - 'no-loop-func': 0, - 'arrow-parens': 0, - 'default-param-last': 0, - semi: 0, - 'operator-linebreak': 0, - 'nonblock-statement-body-position': 0, - curly: 0, - 'implicit-arrow-linebreak': 0, - indent: 0, - 'object-curly-newline': 0, - 'semi-style': 0, - 'function-paren-newline': 0, - 'prefer-template': 0, - 'newline-per-chained-call': 0, - 'prefer-arrow-callback': 0, - 'no-bitwise': 0, - 'prefer-const': 0, - 'no-extra-semi': 0, - }, - ignorePatterns: ['test/data/output', 'lib/css2xpath/*'], -}; diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 439bc4811..bbbcf4c35 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,6 +15,3 @@ updates: ignore: - dependency-name: "escape-string-regexp" versions: [">=5.0"] - - dependency-name: "eslint" - versions: [ ">8.57.0" ] - diff --git a/docs/helpers/Appium.md b/docs/helpers/Appium.md index ab3773a2e..7b9fdab62 100644 --- a/docs/helpers/Appium.md +++ b/docs/helpers/Appium.md @@ -242,10 +242,6 @@ I.runInWeb(() => { }); ``` -#### Parameters - -* `fn` **any** - ### checkIfAppIsInstalled Returns app installation status. diff --git a/docs/plugins.md b/docs/plugins.md index e5b635474..e3a460621 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -20,12 +20,12 @@ It puts a tiny delay for before and after action commands. Commands affected (by default): -- `click` -- `fillField` -- `checkOption` -- `pressKey` -- `doubleClick` -- `rightClick` +* `click` +* `fillField` +* `checkOption` +* `pressKey` +* `doubleClick` +* `rightClick` #### Configuration @@ -39,13 +39,13 @@ plugins: { Possible config options: -- `methods`: list of affected commands. Can be overridden -- `delayBefore`: put a delay before a command. 100ms by default -- `delayAfter`: put a delay after a command. 200ms by default +* `methods`: list of affected commands. Can be overridden +* `delayBefore`: put a delay before a command. 100ms by default +* `delayAfter`: put a delay after a command. 200ms by default ### Parameters -- `config` +* `config` ## autoLogin @@ -80,13 +80,13 @@ Scenario('log me in', ( { I, login } ) => { #### Configuration -- `saveToFile` (default: false) - save cookies to file. Allows to reuse session between execution. -- `inject` (default: `login`) - name of the login function to use -- `users` - an array containing different session names and functions to: - - `login` - sign in into the system - - `check` - check that user is logged in - - `fetch` - to get current cookies (by default `I.grabCookie()`) - - `restore` - to set cookies (by default `I.amOnPage('/'); I.setCookie(cookie)`) +* `saveToFile` (default: false) - save cookies to file. Allows to reuse session between execution. +* `inject` (default: `login`) - name of the login function to use +* `users` - an array containing different session names and functions to: + * `login` - sign in into the system + * `check` - check that user is logged in + * `fetch` - to get current cookies (by default `I.grabCookie()`) + * `restore` - to set cookies (by default `I.amOnPage('/'); I.setCookie(cookie)`) #### How It Works @@ -278,7 +278,7 @@ Scenario('login', async ( {I, login} ) => { ### Parameters -- `config` +* `config` ## commentStep @@ -314,8 +314,8 @@ This plugin can be used ### Config -- `enabled` - (default: false) enable a plugin -- `registerGlobal` - (default: false) register `__` template literal function globally. You can override function global name by providing a name as a value. +* `enabled` - (default: false) enable a plugin +* `registerGlobal` - (default: false) register `__` template literal function globally. You can override function global name by providing a name as a value. ### Examples @@ -364,24 +364,23 @@ const Then = () => step`Then`; ``` Scenario('project update test', async (I) => { - Given(); - const projectId = await I.have('project'); +Given(); +const projectId = await I.have('project'); - When(); - projectPage.update(projectId, { title: 'new title' }); +When(); +projectPage.update(projectId, { title: 'new title' }); - Then(); - projectPage.open(projectId); - I.see('new title', 'h1'); +Then(); +projectPage.open(projectId); +I.see('new title', 'h1'); }); ``` - ``` ### Parameters -- `config` +* `config` ## coverage @@ -402,15 +401,15 @@ plugins: { Possible config options, More could be found at [monocart-coverage-reports][1] -- `debug`: debug info. By default, false. -- `name`: coverage report name. -- `outputDir`: path to coverage report. -- `sourceFilter`: filter the source files. -- `sourcePath`: option to resolve a custom path. +* `debug`: debug info. By default, false. +* `name`: coverage report name. +* `outputDir`: path to coverage report. +* `sourceFilter`: filter the source files. +* `sourcePath`: option to resolve a custom path. ### Parameters -- `config` +* `config` ## customLocator @@ -430,11 +429,11 @@ This plugin will create a valid XPath locator for you. #### Configuration -- `enabled` (default: `false`) should a locator be enabled -- `prefix` (default: `$`) sets a prefix for a custom locator. -- `attribute` (default: `data-test-id`) to set an attribute to be matched. -- `strategy` (default: `xpath`) actual locator strategy to use in query (`css` or `xpath`). -- `showActual` (default: false) show in the output actually produced XPath or CSS locator. By default shows custom locator value. +* `enabled` (default: `false`) should a locator be enabled +* `prefix` (default: `$`) sets a prefix for a custom locator. +* `attribute` (default: `data-test-id`) to set an attribute to be matched. +* `strategy` (default: `xpath`) actual locator strategy to use in query (`css` or `xpath`). +* `showActual` (default: false) show in the output actually produced XPath or CSS locator. By default shows custom locator value. #### Examples: @@ -519,7 +518,7 @@ I.click('=sign-up'); // matches => [data-qa=sign-up],[data-test=sign-up] ### Parameters -- `config` +* `config` ## debugErrors @@ -539,11 +538,11 @@ plugins: { Additional config options: -- `errorClasses` - list of classes to search for errors (default: `['error', 'warning', 'alert', 'danger']`) +* `errorClasses` - list of classes to search for errors (default: `['error', 'warning', 'alert', 'danger']`) ### Parameters -- `config` (optional, default `{}`) +* `config` (optional, default `{}`) ## eachElement @@ -551,9 +550,9 @@ Provides `eachElement` global function to iterate over found elements to perform `eachElement` takes following args: -- `purpose` - the goal of an action. A comment text that will be displayed in output. -- `locator` - a CSS/XPath locator to match elements -- `fn(element, index)` - **asynchronous** function which will be executed for each matched element. +* `purpose` - the goal of an action. A comment text that will be displayed in output. +* `locator` - a CSS/XPath locator to match elements +* `fn(element, index)` - **asynchronous** function which will be executed for each matched element. Example of usage: @@ -588,13 +587,13 @@ This method works with WebDriver, Playwright, Puppeteer, Appium helpers. Function parameter `el` represents a matched element. Depending on a helper API of `el` can be different. Refer to API of corresponding browser testing engine for a complete API list: -- [Playwright ElementHandle][3] -- [Puppeteer][4] -- [webdriverio element][5] +* [Playwright ElementHandle][3] +* [Puppeteer][4] +* [webdriverio element][5] #### Configuration -- `registerGlobal` - to register `eachElement` function globally, true by default +* `registerGlobal` - to register `eachElement` function globally, true by default If `registerGlobal` is false you can use eachElement from the plugin: @@ -604,11 +603,11 @@ const eachElement = codeceptjs.container.plugins('eachElement'); ### Parameters -- `purpose` **[string][6]** -- `locator` **CodeceptJS.LocatorOrString** -- `fn` **[Function][7]** +* `purpose` **[string][6]** +* `locator` **CodeceptJS.LocatorOrString** +* `fn` **[Function][7]** -Returns **([Promise][8]<any> | [undefined][9])** +Returns **([Promise][8]\ | [undefined][9])** ## fakerTransform @@ -620,6 +619,8 @@ To start please install `@faker-js/faker` package npm install -D @faker-js/faker + + yarn add -D @faker-js/faker Add this plugin to config file: @@ -646,7 +647,7 @@ Scenario Outline: ... ### Parameters -- `config` +* `config` ## heal @@ -664,11 +665,11 @@ plugins: { More config options are available: -- `healLimit` - how many steps can be healed in a single test (default: 2) +* `healLimit` - how many steps can be healed in a single test (default: 2) ### Parameters -- `config` (optional, default `{}`) +* `config` (optional, default `{}`) ## pauseOnFail @@ -708,20 +709,20 @@ Run tests with plugin enabled: #### Configuration: -- `retries` - number of retries (by default 3), -- `when` - function, when to perform a retry (accepts error as parameter) -- `factor` - The exponential factor to use. Default is 1.5. -- `minTimeout` - The number of milliseconds before starting the first retry. Default is 1000. -- `maxTimeout` - The maximum number of milliseconds between two retries. Default is Infinity. -- `randomize` - Randomizes the timeouts by multiplying with a factor from 1 to 2. Default is false. -- `defaultIgnoredSteps` - an array of steps to be ignored for retry. Includes: - - `amOnPage` - - `wait*` - - `send*` - - `execute*` - - `run*` - - `have*` -- `ignoredSteps` - an array for custom steps to ignore on retry. Use it to append custom steps to ignored list. +* `retries` - number of retries (by default 3), +* `when` - function, when to perform a retry (accepts error as parameter) +* `factor` - The exponential factor to use. Default is 1.5. +* `minTimeout` - The number of milliseconds before starting the first retry. Default is 1000. +* `maxTimeout` - The maximum number of milliseconds between two retries. Default is Infinity. +* `randomize` - Randomizes the timeouts by multiplying with a factor from 1 to 2. Default is false. +* `defaultIgnoredSteps` - an array of steps to be ignored for retry. Includes: + * `amOnPage` + * `wait*` + * `send*` + * `execute*` + * `run*` + * `have*` +* `ignoredSteps` - an array for custom steps to ignore on retry. Use it to append custom steps to ignored list. You can use step names or step prefixes ending with `*`. As such, `wait*` will match all steps starting with `wait`. To append your own steps to ignore list - copy and paste a default steps list. Regexp values are accepted as well. @@ -753,7 +754,7 @@ Scenario('scenario tite', () => { ### Parameters -- `config` +* `config` ## retryTo @@ -806,13 +807,13 @@ Disables retryFailedStep plugin for steps inside a block; Use this plugin if: -- you need repeat a set of actions in flaky tests -- iframe was not rendered and you need to retry switching to it +* you need repeat a set of actions in flaky tests +* iframe was not rendered and you need to retry switching to it #### Configuration -- `pollInterval` - default interval between retries in ms. 200 by default. -- `registerGlobal` - to register `retryTo` function globally, true by default +* `pollInterval` - default interval between retries in ms. 200 by default. +* `registerGlobal` - to register `retryTo` function globally, true by default If `registerGlobal` is false you can use retryTo from the plugin: @@ -822,7 +823,7 @@ const retryTo = codeceptjs.container.plugins('retryTo'); ### Parameters -- `config` +* `config` ## screenshotOnFail @@ -846,12 +847,12 @@ plugins: { Possible config options: -- `uniqueScreenshotNames`: use unique names for screenshot. Default: false. -- `fullPageScreenshots`: make full page screenshots. Default: false. +* `uniqueScreenshotNames`: use unique names for screenshot. Default: false. +* `fullPageScreenshots`: make full page screenshots. Default: false. ### Parameters -- `config` +* `config` ## selenoid @@ -908,7 +909,7 @@ This is especially useful for Continous Integration server as you can configure 1. Create `browsers.json` file in the same directory `codecept.conf.js` is located [Refer to Selenoid documentation][15] to know more about browsers.json. -_Sample browsers.json_ +*Sample browsers.json* ```js { @@ -968,7 +969,7 @@ When `allure` plugin is enabled a video is attached to report automatically. ### Parameters -- `config` +* `config` ## stepByStepReport @@ -994,17 +995,17 @@ Run tests with plugin enabled: Possible config options: -- `deleteSuccessful`: do not save screenshots for successfully executed tests. Default: true. -- `animateSlides`: should animation for slides to be used. Default: true. -- `ignoreSteps`: steps to ignore in report. Array of RegExps is expected. Recommended to skip `grab*` and `wait*` steps. -- `fullPageScreenshots`: should full page screenshots be used. Default: false. -- `output`: a directory where reports should be stored. Default: `output`. -- `screenshotsForAllureReport`: If Allure plugin is enabled this plugin attaches each saved screenshot to allure report. Default: false. -- \`disableScreenshotOnFail : Disables the capturing of screeshots after the failed step. Default: true. +* `deleteSuccessful`: do not save screenshots for successfully executed tests. Default: true. +* `animateSlides`: should animation for slides to be used. Default: true. +* `ignoreSteps`: steps to ignore in report. Array of RegExps is expected. Recommended to skip `grab*` and `wait*` steps. +* `fullPageScreenshots`: should full page screenshots be used. Default: false. +* `output`: a directory where reports should be stored. Default: `output`. +* `screenshotsForAllureReport`: If Allure plugin is enabled this plugin attaches each saved screenshot to allure report. Default: false. +* \`disableScreenshotOnFail : Disables the capturing of screeshots after the failed step. Default: true. ### Parameters -- `config` **any** +* `config` **any** ## stepTimeout @@ -1026,16 +1027,18 @@ Run tests with plugin enabled: #### Configuration: -- `timeout` - global step timeout, default 150 seconds -- `overrideStepLimits` - whether to use timeouts set in plugin config to override step timeouts set in code with I.limitTime(x).action(...), default false -- `noTimeoutSteps` - an array of steps with no timeout. Default: +* `timeout` - global step timeout, default 150 seconds + +* `overrideStepLimits` - whether to use timeouts set in plugin config to override step timeouts set in code with I.limitTime(x).action(...), default false - - `amOnPage` - - `wait*` +* `noTimeoutSteps` - an array of steps with no timeout. Default: + + * `amOnPage` + * `wait*` you could set your own noTimeoutSteps which would replace the default one. -- `customTimeoutSteps` - an array of step actions with custom timeout. Use it to override or extend noTimeoutSteps. +* `customTimeoutSteps` - an array of step actions with custom timeout. Use it to override or extend noTimeoutSteps. You can use step names or step prefixes ending with `*`. As such, `wait*` will match all steps starting with `wait`. #### Example @@ -1059,7 +1062,7 @@ plugins: { ### Parameters -- `config` +* `config` ## subtitles @@ -1102,15 +1105,16 @@ Disables retryFailedStep plugin for steps inside a block; Use this plugin if: -- you need to perform multiple assertions inside a test -- there is A/B testing on a website you test -- there is "Accept Cookie" banner which may surprisingly appear on a page. +* you need to perform multiple assertions inside a test +* there is A/B testing on a website you test +* there is "Accept Cookie" banner which may surprisingly appear on a page. #### Usage #### Multiple Conditional Assertions ````js + Add assert requires first: ```js const assert = require('assert'); @@ -1121,15 +1125,18 @@ const result1 = await tryTo(() => I.see('Hello, user')); const result2 = await tryTo(() => I.seeElement('.welcome')); assert.ok(result1 && result2, 'Assertions were not succesful'); - ##### Optional click +```` + +##### Optional click - ```js - I.amOnPage('/'); - tryTo(() => I.click('Agree', '.cookies')); +```js +I.amOnPage('/'); +tryTo(() => I.click('Agree', '.cookies')); +```` #### Configuration -- `registerGlobal` - to register `tryTo` function globally, true by default +* `registerGlobal` - to register `tryTo` function globally, true by default If `registerGlobal` is false you can use tryTo from the plugin: @@ -1139,7 +1146,7 @@ const tryTo = codeceptjs.container.plugins('tryTo'); ### Parameters -- `config` +* `config` ## wdio @@ -1147,11 +1154,11 @@ Webdriverio services runner. This plugin allows to run webdriverio services like: -- selenium-standalone -- sauce -- testingbot -- browserstack -- appium +* selenium-standalone +* sauce +* testingbot +* browserstack +* appium A complete list of all available services can be found on [webdriverio website][19]. @@ -1165,7 +1172,7 @@ See examples below: #### Selenium Standalone Service -Install `@wdio/selenium-standalone-service` package, as [described here][20]. +Install ` @wdio/selenium-standalone-service` package, as [described here][20]. It is important to make sure it is compatible with current webdriverio version. Enable `wdio` plugin in plugins list and add `selenium-standalone` service: @@ -1199,18 +1206,18 @@ plugins: { } ``` -* * * +*** In the same manner additional services from webdriverio can be installed, enabled, and configured. #### Configuration -- `services` - list of enabled services -- ... - additional configuration passed into services. +* `services` - list of enabled services +* ... - additional configuration passed into services. ### Parameters -- `config` +* `config` [1]: https://github.com/cenfun/monocart-coverage-reports?tab=readme-ov-file#default-options diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..9884b4975 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,81 @@ +import globals from "globals"; +import path from "node:path"; +import {fileURLToPath} from "node:url"; +import js from "@eslint/js"; +import {FlatCompat} from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}); + +export default [{ + ignores: ["test/data/output", "lib/css2xpath/*"], +}, ...compat.extends("airbnb-base"), { + languageOptions: { + globals: { + ...globals.node, + }, + + ecmaVersion: 2020, + sourceType: "commonjs", + }, + + rules: { + "func-names": 0, + "no-use-before-define": 0, + "no-unused-vars": 0, + "no-underscore-dangle": 0, + "no-undef": 0, + "prefer-destructuring": 0, + "no-param-reassign": 0, + "max-len": 0, + camelcase: 0, + "no-shadow": 0, + "consistent-return": 0, + "no-console": 0, + "global-require": 0, + "class-methods-use-this": 0, + "no-plusplus": 0, + "no-return-assign": 0, + "prefer-rest-params": 0, + "no-useless-escape": 0, + "no-restricted-syntax": 0, + "no-unused-expressions": 0, + "guard-for-in": 0, + "no-multi-assign": 0, + "require-yield": 0, + "prefer-spread": 0, + "import/no-dynamic-require": 0, + "no-continue": 0, + "no-mixed-operators": 0, + "default-case": 0, + "import/no-extraneous-dependencies": 0, + "no-cond-assign": 0, + "import/no-unresolved": 0, + "no-await-in-loop": 0, + "arrow-body-style": 0, + "no-loop-func": 0, + "arrow-parens": 0, + "default-param-last": 0, + semi: 0, + "operator-linebreak": 0, + "nonblock-statement-body-position": 0, + curly: 0, + "implicit-arrow-linebreak": 0, + indent: 0, + "object-curly-newline": 0, + "semi-style": 0, + "function-paren-newline": 0, + "prefer-template": 0, + "newline-per-chained-call": 0, + "prefer-arrow-callback": 0, + "no-bitwise": 0, + "prefer-const": 0, + "no-extra-semi": 0, + "max-classes-per-file": 0 + }, +}]; diff --git a/examples/fragments/Signin.js b/examples/fragments/Signin.js index 03382780a..7d7b018f0 100644 --- a/examples/fragments/Signin.js +++ b/examples/fragments/Signin.js @@ -1,4 +1,3 @@ -/* eslint-disable */ let I; module.exports = { diff --git a/examples/pages/Admin.js b/examples/pages/Admin.js index 03382780a..7d7b018f0 100644 --- a/examples/pages/Admin.js +++ b/examples/pages/Admin.js @@ -1,4 +1,3 @@ -/* eslint-disable */ let I; module.exports = { diff --git a/lib/command/gherkin/snippets.js b/lib/command/gherkin/snippets.js index e0f92e11a..c26236916 100644 --- a/lib/command/gherkin/snippets.js +++ b/lib/command/gherkin/snippets.js @@ -127,6 +127,6 @@ ${step.type}(${step.regexp ? '/^' : "'"}${step}${step.regexp ? '$/' : "'"}, () = if (!options.dryRun) { output.success(`Snippets added to ${output.colors.bold(stepFile)}`); - fs.writeFileSync(stepFile, fs.readFileSync(stepFile).toString() + snippets.join('\n') + '\n'); // eslint-disable-line + fs.writeFileSync(stepFile, fs.readFileSync(stepFile).toString() + snippets.join('\n') + '\n'); } }; diff --git a/lib/command/workers/runTests.js b/lib/command/workers/runTests.js index 48ce85127..0ab4af468 100644 --- a/lib/command/workers/runTests.js +++ b/lib/command/workers/runTests.js @@ -13,9 +13,8 @@ const container = require('../../container'); const { getConfig } = require('../utils'); const { tryOrDefault, deepMerge } = require('../../utils'); -// eslint-disable-next-line no-unused-vars let stdout = ''; -/* eslint-enable no-unused-vars */ + const stderr = ''; // Requiring of Codecept need to be after tty.getWindowSize is available. diff --git a/lib/heal.js b/lib/heal.js index b6071c456..e1a3ce51d 100644 --- a/lib/heal.js +++ b/lib/heal.js @@ -113,7 +113,7 @@ class Heal { }); if (typeof codeSnippet === 'string') { - const I = Container.support('I'); // eslint-disable-line + const I = Container.support('I'); await eval(codeSnippet); // eslint-disable-line } else if (typeof codeSnippet === 'function') { await codeSnippet(Container.support()); diff --git a/lib/helper/Appium.js b/lib/helper/Appium.js index ff7e7953a..9c476cc56 100644 --- a/lib/helper/Appium.js +++ b/lib/helper/Appium.js @@ -491,17 +491,15 @@ class Appium extends Webdriver { * }); * ``` * - * @param {*} fn */ - /* eslint-disable */ - async runInWeb(fn) { + + async runInWeb() { if (!this.isWeb) return recorder.session.start('Web-only actions') recorder.add('restore from Web session', () => recorder.session.restore(), true) return recorder.promise() } - /* eslint-enable */ _runWithCaps(caps, fn) { if (typeof caps === 'object') { @@ -1077,7 +1075,7 @@ class Appium extends Webdriver { * * Appium: support Android and iOS */ - /* eslint-disable */ + async swipe(locator, xoffset, yoffset, speed = 1000) { onlyForApps.call(this) const res = await this.browser.$(parseLocator.call(this, locator)) @@ -1087,7 +1085,6 @@ class Appium extends Webdriver { y: (await res.getLocation()).y + yoffset, }) } - /* eslint-enable */ /** * Perform a swipe on the screen. diff --git a/lib/helper/Nightmare.js b/lib/helper/Nightmare.js index d89fc520a..1a6e90692 100644 --- a/lib/helper/Nightmare.js +++ b/lib/helper/Nightmare.js @@ -1324,7 +1324,7 @@ class Nightmare extends Helper { offsetY, ) } - // eslint-disable-next-line prefer-arrow-callback + return this.executeScript( function (x, y) { return window.scrollTo(x, y) @@ -1345,7 +1345,6 @@ class Nightmare extends Helper { * {{> scrollPageToBottom }} */ async scrollPageToBottom() { - /* eslint-disable prefer-arrow-callback, comma-dangle */ return this.executeScript(function () { const body = document.body const html = document.documentElement @@ -1354,21 +1353,19 @@ class Nightmare extends Helper { Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight), ) }) - /* eslint-enable */ } /** * {{> grabPageScrollPosition }} */ async grabPageScrollPosition() { - /* eslint-disable comma-dangle */ function getScrollPosition() { return { x: window.pageXOffset, y: window.pageYOffset, } } - /* eslint-enable comma-dangle */ + return this.executeScript(getScrollPosition) } } diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 5210fb69c..1f606adf4 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -1241,14 +1241,13 @@ class Playwright extends Helper { * {{> grabPageScrollPosition }} */ async grabPageScrollPosition() { - /* eslint-disable comma-dangle */ function getScrollPosition() { return { x: window.pageXOffset, y: window.pageYOffset, } } - /* eslint-enable comma-dangle */ + return this.executeScript(getScrollPosition) } @@ -2839,7 +2838,7 @@ class Playwright extends Helper { } } else { // we have this as https://github.com/microsoft/playwright/issues/26829 is not yet implemented - // eslint-disable-next-line no-lonely-if + const _contextObject = this.frame ? this.frame : contextObject let count = 0 do { @@ -3816,7 +3815,6 @@ function parseWindowSize(windowSize) { // List of key values to key definitions // https://github.com/puppeteer/puppeteer/blob/v1.20.0/lib/USKeyboardLayout.js const keyDefinitionMap = { - /* eslint-disable quote-props */ 0: 'Digit0', 1: 'Digit1', 2: 'Digit2', @@ -3864,7 +3862,6 @@ const keyDefinitionMap = { '\\': 'Backslash', ']': 'BracketRight', "'": 'Quote', - /* eslint-enable quote-props */ } function getNormalizedKey(key) { diff --git a/lib/helper/Protractor.js b/lib/helper/Protractor.js index 9b785d33e..0fab33d11 100644 --- a/lib/helper/Protractor.js +++ b/lib/helper/Protractor.js @@ -595,7 +595,6 @@ class Protractor extends Helper { async pressKey(key) { let modifier if (Array.isArray(key) && ~['Control', 'Command', 'Shift', 'Alt'].indexOf(key[0])) { - // eslint-disable-line no-bitwise modifier = Key[key[0].toUpperCase()] key = key[1] } @@ -1106,7 +1105,6 @@ class Protractor extends Helper { } let { width, height } = await this.browser.executeScript(() => ({ - // eslint-disable-line height: document.body.scrollHeight, width: document.body.scrollWidth, })) @@ -1614,7 +1612,7 @@ class Protractor extends Helper { } const elem = res[0] const location = await elem.getLocation() - /* eslint-disable prefer-arrow-callback */ + return this.executeScript( function (x, y) { return window.scrollTo(x, y) @@ -1622,10 +1620,8 @@ class Protractor extends Helper { location.x + offsetX, location.y + offsetY, ) - /* eslint-enable */ } - /* eslint-disable prefer-arrow-callback, comma-dangle */ return this.executeScript( function (x, y) { return window.scrollTo(x, y) @@ -1633,7 +1629,6 @@ class Protractor extends Helper { offsetX, offsetY, ) - /* eslint-enable */ } /** @@ -1647,7 +1642,6 @@ class Protractor extends Helper { * {{> scrollPageToBottom }} */ async scrollPageToBottom() { - /* eslint-disable prefer-arrow-callback, comma-dangle */ return this.executeScript(function () { const body = document.body const html = document.documentElement @@ -1656,21 +1650,19 @@ class Protractor extends Helper { Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight), ) }) - /* eslint-enable */ } /** * {{> grabPageScrollPosition }} */ async grabPageScrollPosition() { - /* eslint-disable comma-dangle */ function getScrollPosition() { return { x: window.pageXOffset, y: window.pageYOffset, } } - /* eslint-enable comma-dangle */ + return this.executeScript(getScrollPosition) } diff --git a/lib/helper/Puppeteer.js b/lib/helper/Puppeteer.js index 9bc82b69d..77cbf3587 100644 --- a/lib/helper/Puppeteer.js +++ b/lib/helper/Puppeteer.js @@ -861,14 +861,13 @@ class Puppeteer extends Helper { * {{> grabPageScrollPosition }} */ async grabPageScrollPosition() { - /* eslint-disable comma-dangle */ function getScrollPosition() { return { x: window.pageXOffset, y: window.pageYOffset, } } - /* eslint-enable comma-dangle */ + return this.executeScript(getScrollPosition) } @@ -3106,7 +3105,6 @@ async function getClickablePoint(el) { // List of key values to key definitions // https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/lib/USKeyboardLayout.js const keyDefinitionMap = { - /* eslint-disable quote-props */ 0: 'Digit0', 1: 'Digit1', 2: 'Digit2', @@ -3154,7 +3152,6 @@ const keyDefinitionMap = { '\\': 'Backslash', ']': 'BracketRight', "'": 'Quote', - /* eslint-enable quote-props */ } function getNormalizedKey(key) { diff --git a/lib/helper/TestCafe.js b/lib/helper/TestCafe.js index 86f27bc5b..a853860df 100644 --- a/lib/helper/TestCafe.js +++ b/lib/helper/TestCafe.js @@ -1049,7 +1049,6 @@ class TestCafe extends Helper { } const getCookie = ClientFunction( () => { - // eslint-disable-next-line prefer-template const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)') return v ? v[2] : null }, @@ -1220,12 +1219,11 @@ async function waitForFunction(browserFn, waitTimeout) { }) const start = Date.now() - // eslint-disable-next-line no-constant-condition + while (true) { let result try { result = await browserFn() - // eslint-disable-next-line no-empty } catch (err) { throw new Error(`Error running function ${err.toString()}`) } diff --git a/lib/helper/WebDriver.js b/lib/helper/WebDriver.js index 2065deaec..98c5283e4 100644 --- a/lib/helper/WebDriver.js +++ b/lib/helper/WebDriver.js @@ -1774,7 +1774,7 @@ class WebDriver extends Helper { if (this.browser.isMobile && !this.browser.isW3C) return this.browser.touchScroll(offsetX, offsetY, elementId) const location = await elem.getLocation() assertElementExists(location, locator, 'Failed to receive', 'location') - /* eslint-disable prefer-arrow-callback */ + return this.browser.execute( function (x, y) { return window.scrollTo(x, y) @@ -1782,12 +1782,10 @@ class WebDriver extends Helper { location.x + offsetX, location.y + offsetY, ) - /* eslint-enable */ } if (this.browser.isMobile && !this.browser.isW3C) return this.browser.touchScroll(locator, offsetX, offsetY) - /* eslint-disable prefer-arrow-callback, comma-dangle */ return this.browser.execute( function (x, y) { return window.scrollTo(x, y) @@ -1795,7 +1793,6 @@ class WebDriver extends Helper { offsetX, offsetY, ) - /* eslint-enable */ } /** @@ -1854,7 +1851,6 @@ class WebDriver extends Helper { return this.browser.saveScreenshot(outputFile) } - /* eslint-disable prefer-arrow-callback, comma-dangle, prefer-const */ const originalWindowSize = await this.browser.getWindowSize() let { width, height } = await this.browser @@ -1867,7 +1863,6 @@ class WebDriver extends Helper { .then((res) => res) if (height < 100) height = 500 // errors for very small height - /* eslint-enable */ await this.browser.setWindowSize(width, height) this.debug(`Screenshot has been saved to ${outputFile}, size: ${width}x${height}`) @@ -2673,11 +2668,10 @@ class WebDriver extends Helper { */ scrollPageToTop() { const client = this.browser - /* eslint-disable prefer-arrow-callback */ + return client.execute(function () { window.scrollTo(0, 0) }) - /* eslint-enable */ } /** @@ -2685,7 +2679,7 @@ class WebDriver extends Helper { */ scrollPageToBottom() { const client = this.browser - /* eslint-disable prefer-arrow-callback, comma-dangle */ + return client.execute(function () { const body = document.body const html = document.documentElement @@ -2694,21 +2688,19 @@ class WebDriver extends Helper { Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight), ) }) - /* eslint-enable */ } /** * {{> grabPageScrollPosition }} */ async grabPageScrollPosition() { - /* eslint-disable comma-dangle */ function getScrollPosition() { return { x: window.pageXOffset, y: window.pageYOffset, } } - /* eslint-enable comma-dangle */ + return this.executeScript(getScrollPosition) } @@ -2733,7 +2725,7 @@ class WebDriver extends Helper { * @param {*} caps * @param {*} fn */ - /* eslint-disable */ + runOnIOS(caps, fn) {} /** @@ -2742,12 +2734,11 @@ class WebDriver extends Helper { * @param {*} fn */ runOnAndroid(caps, fn) {} - /* eslint-enable */ /** * Placeholder for ~ locator only test case write once run on both Appium and WebDriver. */ - runInWeb(fn) { + async runInWeb(fn) { return fn() } } @@ -3032,7 +3023,6 @@ function getElementId(el) { // List of known key values to unicode code points // https://www.w3.org/TR/webdriver/#keyboard-actions const keyUnicodeMap = { - /* eslint-disable quote-props */ Unidentified: '\uE000', Cancel: '\uE001', Clear: '\uE005', @@ -3147,7 +3137,6 @@ const keyUnicodeMap = { Semicolon: '\uE018', // ';' alias Slash: '/', // '/' alias ZenkakuHankaku: '\uE040', - /* eslint-enable quote-props */ } function convertKeyToRawKey(key) { diff --git a/lib/helper/extras/PlaywrightPropEngine.js b/lib/helper/extras/PlaywrightPropEngine.js index c74f17f19..5d9054159 100644 --- a/lib/helper/extras/PlaywrightPropEngine.js +++ b/lib/helper/extras/PlaywrightPropEngine.js @@ -2,7 +2,7 @@ module.exports.createValueEngine = () => { return { // Creates a selector that matches given target when queried at the root. // Can return undefined if unable to create one. - // eslint-disable-next-line no-unused-vars + create(root, target) { return null; }, @@ -29,7 +29,7 @@ module.exports.createDisabledEngine = () => { return { // Creates a selector that matches given target when queried at the root. // Can return undefined if unable to create one. - // eslint-disable-next-line no-unused-vars + create(root, target) { return null; }, diff --git a/lib/helper/network/utils.js b/lib/helper/network/utils.js index 7b34ec342..7e3c88bc9 100644 --- a/lib/helper/network/utils.js +++ b/lib/helper/network/utils.js @@ -34,7 +34,7 @@ const extractQueryObjects = (queryString) => { queryParameters.forEach((queryParameter) => { const keyValue = queryParameter.split('='); const queryObject = {}; - // eslint-disable-next-line prefer-destructuring + queryObject.name = keyValue[0]; queryObject.value = decodeURIComponent(keyValue[1]); queryObjects.push(queryObject); diff --git a/lib/helper/testcafe/testcafe-utils.js b/lib/helper/testcafe/testcafe-utils.js index 2d001b847..c44176e26 100644 --- a/lib/helper/testcafe/testcafe-utils.js +++ b/lib/helper/testcafe/testcafe-utils.js @@ -48,7 +48,7 @@ function getFuncBody(func) { const arrowIndex = fnStr.indexOf('=>'); if (arrowIndex >= 0) { fnStr = fnStr.slice(arrowIndex + 2); - // eslint-disable-next-line no-new-func + // eslint-disable-next-line no-eval return eval(`() => ${fnStr}`); } diff --git a/lib/output.js b/lib/output.js index cb15f7e1d..c0974be58 100644 --- a/lib/output.js +++ b/lib/output.js @@ -117,7 +117,7 @@ module.exports = { stepLine = colors.green(truncate(stepLine, this.spaceShift)); } if (step.comment) { - stepLine += colors.grey(step.comment.split('\n').join('\n' + ' '.repeat(4))); // eslint-disable-line + stepLine += colors.grey(step.comment.split('\n').join('\n' + ' '.repeat(4))); } print(' '.repeat(this.stepShift), truncate(stepLine, this.spaceShift)); @@ -168,9 +168,9 @@ module.exports = { /** * @param {Mocha.Test} test */ - /* eslint-disable */ + started(test) {}, - /* eslint-enable */ + /** * @param {Mocha.Test} test */ diff --git a/lib/pause.js b/lib/pause.js index 8e6fb7f04..2b4c5e6ce 100644 --- a/lib/pause.js +++ b/lib/pause.js @@ -91,7 +91,7 @@ async function parseInput(cmd) { return nextStep(); } for (const k of Object.keys(registeredVariables)) { - eval(`var ${k} = registeredVariables['${k}'];`); // eslint-disable-line no-eval + eval(`var ${k} = registeredVariables['${k}'];`); } let executeCommand = Promise.resolve(); @@ -106,9 +106,9 @@ async function parseInput(cmd) { let isAiCommand = false; let $res; try { - // eslint-disable-next-line + const locate = global.locate; // enable locate in this context - // eslint-disable-next-line + const I = container.support('I'); if (cmd.trim().startsWith('=>')) { isCustomCommand = true; @@ -143,7 +143,7 @@ async function parseInput(cmd) { executeCommand = executeCommand.then(async () => { const cmd = getCmd(); if (!cmd) return; - return eval(cmd); // eslint-disable-line no-eval + return eval(cmd); }).catch((err) => { debug(err); if (isAiCommand) return; @@ -156,7 +156,7 @@ async function parseInput(cmd) { const val = await executeCommand; if (isCustomCommand) { - if (val !== undefined) console.log('Result', '$res=', val); // eslint-disable-line + if (val !== undefined) console.log('Result', '$res=', val); $res = val; } diff --git a/lib/secret.js b/lib/secret.js index 38786bcf6..2ea52a8da 100644 --- a/lib/secret.js +++ b/lib/secret.js @@ -1,4 +1,3 @@ -/* eslint-disable max-classes-per-file */ const { deepClone } = require('./utils'); const maskedString = '*****'; diff --git a/lib/step.js b/lib/step.js index c9184fad3..39d79c596 100644 --- a/lib/step.js +++ b/lib/step.js @@ -1,5 +1,5 @@ // TODO: place MetaStep in other file, disable rule -/* eslint-disable max-classes-per-file */ + const store = require('./store'); const Secret = require('./secret'); const event = require('./event'); diff --git a/lib/workers.js b/lib/workers.js index 429091b36..7ba617d9c 100644 --- a/lib/workers.js +++ b/lib/workers.js @@ -1,4 +1,3 @@ -/* eslint-disable max-classes-per-file */ const path = require('path'); const mkdirp = require('mkdirp'); const { Worker } = require('worker_threads'); diff --git a/package.json b/package.json index a2a21e78a..7dc2a9b37 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,8 @@ }, "devDependencies": { "@codeceptjs/mock-request": "0.3.1", + "@eslint/eslintrc": "3.1.0", + "@eslint/js": "9.14.0", "@faker-js/faker": "9.2.0", "@pollyjs/adapter-puppeteer": "6.0.6", "@pollyjs/core": "5.1.0", @@ -135,12 +137,13 @@ "contributor-faces": "1.1.0", "documentation": "14.0.3", "electron": "33.2.0", - "eslint": "8.57.0", + "eslint": "9.14.0", "eslint-config-airbnb-base": "15.0.0", - "eslint-plugin-import": "2.30.0", + "eslint-plugin-import": "2.31.0", "eslint-plugin-mocha": "10.5.0", "expect": "29.7.0", "express": "4.21.1", + "globals": "15.12.0", "graphql": "16.9.0", "husky": "9.1.6", "inquirer-test": "2.0.1", diff --git a/test/data/sandbox/configs/commentStep/customHelper.js b/test/data/sandbox/configs/commentStep/customHelper.js index 4bdac5fa6..84fb53544 100644 --- a/test/data/sandbox/configs/commentStep/customHelper.js +++ b/test/data/sandbox/configs/commentStep/customHelper.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ // const Helper = require('../../lib/helper'); class CustomHelper extends Helper { diff --git a/test/data/sandbox/configs/testArtifacts/customHelper.js b/test/data/sandbox/configs/testArtifacts/customHelper.js index 1c215f42b..9eb4bd15c 100644 --- a/test/data/sandbox/configs/testArtifacts/customHelper.js +++ b/test/data/sandbox/configs/testArtifacts/customHelper.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ // const Helper = require('../../lib/helper'); class CustomHelper extends Helper { diff --git a/test/data/sandbox/features/step_definitions/my_other_steps.js b/test/data/sandbox/features/step_definitions/my_other_steps.js index 7605179b6..2f18a006e 100644 --- a/test/data/sandbox/features/step_definitions/my_other_steps.js +++ b/test/data/sandbox/features/step_definitions/my_other_steps.js @@ -1,7 +1,7 @@ const I = actor(); const axios = require('axios'); -Given('I have products in my cart', (table) => { // eslint-disable-line +Given('I have products in my cart', (table) => { for (const id in table.rows) { if (id < 1) { continue; diff --git a/test/data/sandbox/support/failureHelper.js b/test/data/sandbox/support/failureHelper.js index 24a2cb2a6..a1b48ce3d 100644 --- a/test/data/sandbox/support/failureHelper.js +++ b/test/data/sandbox/support/failureHelper.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ // const Helper = require('../../lib/helper'); class FailureHelper extends Helper { diff --git a/test/data/sandbox/testscenario_test.testscenario.js b/test/data/sandbox/testscenario_test.testscenario.js index 43791005e..0f6ca54c0 100644 --- a/test/data/sandbox/testscenario_test.testscenario.js +++ b/test/data/sandbox/testscenario_test.testscenario.js @@ -9,7 +9,6 @@ Scenario('Simple async/await test', async ({ I }) => { console.log(text); }); -// eslint-disable-next-line arrow-parens Scenario('Should understand async without brackets', async ({ I }) => { const text = await I.stringWithScenarioType('asyncbrackets'); console.log(text); diff --git a/test/unit/parser_test.js b/test/unit/parser_test.js index 331d3b50e..5748fca2c 100644 --- a/test/unit/parser_test.js +++ b/test/unit/parser_test.js @@ -4,7 +4,6 @@ import('chai').then((chai) => { }) const parser = require('../../lib/parser') -/* eslint-disable no-unused-vars */ class Obj { method1(locator, sec) {} diff --git a/test/unit/utils_test.js b/test/unit/utils_test.js index 1a4aef63f..77a968806 100644 --- a/test/unit/utils_test.js +++ b/test/unit/utils_test.js @@ -14,7 +14,7 @@ describe('utils', () => { it('not exists', () => expect(utils.fileExists('not_utils.js')).to.be.false) it('not exists if file used as directory', () => expect(utils.fileExists(`${__filename}/not_utils.js`)).to.be.false) }) - /* eslint-disable no-unused-vars */ + describe('#getParamNames', () => { it('fn#1', () => expect(utils.getParamNames((a, b) => {})).eql(['a', 'b'])) it('fn#2', () => expect(utils.getParamNames((I, userPage) => {})).eql(['I', 'userPage'])) @@ -23,7 +23,6 @@ describe('utils', () => { it('should handle trailing comma', () => expect(utils.getParamNames((I, trailing, comma) => {})).eql(['I', 'trailing', 'comma'])) }) - /* eslint-enable no-unused-vars */ describe('#methodsOfObject', () => { it('should get methods', () => {