From 06cedb04c1e5bc97b81cb029bf3814edec97d553 Mon Sep 17 00:00:00 2001 From: David Sveningsson Date: Mon, 19 Nov 2018 15:53:41 +0100 Subject: [PATCH] fix(rules): fix handling of multiple arguments in no-repetitive-locators Closes #89 --- lib/get-locator.js | 18 ++++++++++++++---- lib/rules/no-repetitive-locators.js | 24 +++++++++++++++++++++++- test/rules/no-repetitive-locators.js | 25 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/get-locator.js b/lib/get-locator.js index 05b71ae..27a03c1 100644 --- a/lib/get-locator.js +++ b/lib/get-locator.js @@ -4,6 +4,13 @@ * @fileoverview Utility function to extract the "by" locator values. Also handles the "$" and "$$" shortcuts. * @author Alexander Afanasyev */ + +function onlyLiteralArguments (node) { + return node.arguments.every(function (arg) { + return arg.type === 'Literal' + }) +} + module.exports = function (node) { var object = node.callee.object var property = node.callee.property @@ -14,20 +21,23 @@ module.exports = function (node) { // handling by.smth calls if (insideBy) { - var hasArgument = node.arguments && node.arguments.length && node.arguments[0].hasOwnProperty('value') - if (hasArgument) { + var hasArgument = node.arguments && node.arguments.length + if (hasArgument && onlyLiteralArguments(node)) { return { by: property.name, - value: node.arguments[0].value + value: node.arguments.map(function (arg) { + return arg.value + }) } } } // handling $ and $$ calls if (dollarShortcuts || chainedDollarShortcuts) { + var value = node.arguments[0].value return { by: 'css', - value: node.arguments[0].value + value: value ? [value] : undefined } } } diff --git a/lib/rules/no-repetitive-locators.js b/lib/rules/no-repetitive-locators.js index 22d8fbd..765ba5b 100644 --- a/lib/rules/no-repetitive-locators.js +++ b/lib/rules/no-repetitive-locators.js @@ -16,12 +16,34 @@ module.exports = { // locators collects locators grouped by type, e.g.: {css: [".test", "div:first-of-type"], id: ["myid1", "myid2"]} var locators = {} + function arrayEquals (a, b) { + if (a.length !== b.length) { + return false + } + for (var i = 0; i < a.length; i++) { + if (a[i] !== b[i]) { + return false + } + } + return true + } + + function matchExisting (calls, currentArgs) { + if (!calls) { + return false + } + + return calls.some(function matchArgs (args) { + return arrayEquals(args, currentArgs) + }) + } + return { CallExpression: function (node) { var locator = getLocator(node) if (locator && locator.value) { // find exact locator duplicates (both by and value were met before) - if (locator.by in locators && locators[locator.by].indexOf(locator.value) >= 0) { + if (matchExisting(locators[locator.by], locator.value)) { context.report({ node: node, message: 'Repetitive locator detected' diff --git a/test/rules/no-repetitive-locators.js b/test/rules/no-repetitive-locators.js index 70fb422..33df235 100644 --- a/test/rules/no-repetitive-locators.js +++ b/test/rules/no-repetitive-locators.js @@ -14,6 +14,18 @@ eslintTester.run('no-repetitive-locators', rule, { ' this.firstGrid = this.grids.first();', '}' ]), + toCode([ + 'var MyPage = function () {', + ' this.dogs = element.all(by.cssContainingText("p", "Dog"));', + ' this.cats = element.all(by.cssContainingText("p", "Cat"));', + '}' + ]), + toCode([ + 'var MyPage = function () {', + ' this.dogs = element.all(by.cssContainingText("p", "Dog"));', + ' this.cats = element.all(by.cssContainingText("i", "Dog"));', + '}' + ]), toCode([ 'var MyPage = function () {', ' this.parent = $(".container #parent");', @@ -38,6 +50,19 @@ eslintTester.run('no-repetitive-locators', rule, { ], invalid: [ + { + code: toCode([ + 'var MyPage = function () {', + ' this.a = element.all(by.cssContainingText("p", "Dog"));', + ' this.b = element.all(by.cssContainingText("p", "Dog"));', + '}' + ]), + errors: [ + { + message: 'Repetitive locator detected' + } + ] + }, { code: toCode([ 'var MyPage = function () {',