diff --git a/lib/rules/unsafe-to-chain-command.js b/lib/rules/unsafe-to-chain-command.js index fb959338..6c644f3e 100644 --- a/lib/rules/unsafe-to-chain-command.js +++ b/lib/rules/unsafe-to-chain-command.js @@ -9,6 +9,8 @@ const DESCRIPTION = 'Actions should be in the end of chains, not in the middle' * Commands listed in the documentation with text: 'It is unsafe to chain further commands that rely on the subject after xxx.' * See {@link https://docs.cypress.io/guides/core-concepts/retry-ability#Actions-should-be-at-the-end-of-chains-not-the-middle Actions should be at the end of chains, not the middle} * for more information. + * + * @type {string[]} */ const unsafeToChainActions = [ 'blur', @@ -32,20 +34,9 @@ const unsafeToChainActions = [ 'within', ] -const getDefaultOptions = (schema, context) => { - return { - ...Object.entries(schema.properties).reduce((acc, [key, value]) => { - if (value.default === undefined) return acc - - return { - ...acc, - [key]: value.default, - } - }, {}), - ...context.options[0], - } -} - +/** + * @type {import('eslint').Rule.RuleMetaData['schema']} + */ const schema = { title: NAME, description: DESCRIPTION, @@ -60,6 +51,21 @@ const schema = { }, } +/** + * @param {import('eslint').Rule.RuleContext} context + * @returns {Record} + */ +const getDefaultOptions = (context) => { + return Object.entries(schema.properties).reduce((acc, [key, value]) => { + if (!(value.default in value)) return acc + + return { + ...acc, + [key]: value.default, + } + }, context.options[0] || {}) +} + /** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { @@ -76,7 +82,7 @@ module.exports = { }, }, create (context) { - const { methods } = getDefaultOptions(schema, context) + const { methods } = getDefaultOptions(context) return { CallExpression (node) { @@ -95,8 +101,17 @@ module.exports = { }, } -function isRootCypress (node) { - if (node.type !== 'CallExpression' || node.callee.type !== 'MemberExpression') return +/** + * @param {import('estree').Node} node + * @returns {boolean} + */ +const isRootCypress = (node) => { + if ( + node.type !== 'CallExpression' || + node.callee.type !== 'MemberExpression' + ) { + return false + } if ( node.callee.object.type === 'Identifier' && @@ -108,7 +123,11 @@ function isRootCypress (node) { return isRootCypress(node.callee.object) } -function isActionUnsafeToChain (node, additionalMethods) { +/** + * @param {import('estree').Node} node + * @param {string[] | RegExp[]} additionalMethods + */ +const isActionUnsafeToChain = (node, additionalMethods = []) => { const unsafeActionsRegex = new RegExp([ ...unsafeToChainActions, ...additionalMethods.map((method) => method instanceof RegExp ? method.source : method),