From 3ede9fa6b5b1f7ad09b2c9f1d5d364baf68be885 Mon Sep 17 00:00:00 2001 From: Alexander Afanasyev Date: Wed, 21 Jun 2017 15:16:29 -0400 Subject: [PATCH] feat(rules): add 'no-get-raw-id' rule --- README.md | 3 +++ docs/rules/no-get-raw-id.md | 28 +++++++++++------------ index.js | 5 ++++- lib/is-element-finder.js | 15 ++++++++++++- lib/rules/no-get-raw-id.js | 18 +++++++-------- test/rules/no-get-raw-id.js | 44 ++++++++++++++++++++++--------------- 6 files changed, 68 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 9b97d58..e36eeff 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ There are various types of rules implemented in the plugin. Here is a rough cate * [no-array-finder-methods][]: Disallow using `ElementArrayFinder` methods on `ElementFinder` * [array-callback-return][]: Enforce `return` statements in callbacks of `ElementArrayFinder` methods * [no-get-inner-outer-html][]: Warn about using deprecated `getInnerHtml()` and `getOuterHtml()` methods +* [no-get-raw-id][]: Warn about using removed `getRawId()` method * [no-promise-in-if][]: Warn if promise is checked for truthiness inside an `if` condition #### Locating Elements @@ -105,6 +106,7 @@ Rule | Default Error Level | Auto-fixable | Options [no-array-finder-methods][] | 2 | | [valid-locator-type][] | 2 | | [no-compound-classes][] | 2 | | +[no-get-raw-id][] | 2 | | [missing-wait-message][] | 1 (Warning) | | [no-browser-sleep][] | 1 | | [no-by-xpath][] | 1 | | @@ -182,6 +184,7 @@ See [configuring rules][] for more information. [no-browser-driver]: docs/rules/no-browser-driver.md [valid-by-id]: docs/rules/valid-by-id.md [valid-by-tagname]: docs/rules/valid-by-tagname.md +[no-get-raw-id]: docs/rules/no-get-raw-id.md [configuring rules]: http://eslint.org/docs/user-guide/configuring#configuring-rules ## Recommended configuration diff --git a/docs/rules/no-get-raw-id.md b/docs/rules/no-get-raw-id.md index b576967..c1adb95 100644 --- a/docs/rules/no-get-raw-id.md +++ b/docs/rules/no-get-raw-id.md @@ -1,27 +1,25 @@ -# Warn about using deprecated `getInnerHtml()` and `getOuterHtml()` methods +# Warn about using removed `getRawId()` method -Selenium [has deprecated `getInnerHtml()` and `getOuterHtml()` methods in version 2.53](https://github.com/SeleniumHQ/selenium/blob/96ed95a97405fa267eea09c4008cda9e7703e84d/javascript/node/selenium-webdriver/CHANGES.md#change-summary). -And, hence, Protractor itself _does not have these methods documented_ as a part of [public API](http://www.protractortest.org/#/api) anymore. +`getRawId()` method has been removed in [`Protractor` 5.0.0](https://github.com/angular/protractor/blob/ea72d5588aef983aa84705abd1ad1afa36065be7/CHANGELOG.md#500) and in [`Selenium` 3.0.0](https://github.com/SeleniumHQ/selenium/blob/427307d6e24000d7db68e8c36362fab05c477cce/javascript/node/selenium-webdriver/CHANGES.md#v300-beta-1). +Use `getId()` method instead. ## Rule details -Any use of the following patterns are considered warnings: +Any use of the following patterns are considered errors: ```js -expect(element(by.id("myid")).getInnerHtml()).toEqual("test"); -expect(element(by.id("myid")).getOuterHtml()).toEqual("test"); -element.all(by.css(".class")).first().getOuterHtml(); -element(by.id("id")).all(by.css(".class")).last().getInnerHtml(); -$$(".class").first().getOuterHtml(); -$(".class").getInnerHtml().then(function (html) { console.log(html) }); +expect(element(by.id("myid")).getRawId()).toEqual("id"); +element.all(by.css(".class")).first().getRawId(); +element(by.id("id")).all(by.css(".class")).last().getRawId(); +$$(".class").first().getRawId(); +$(".class").getRawId().then(function (id) { console.log(id) }); ``` The following patterns are not warnings: ```js -expect(element(by.id("myid")).getText()).toEqual("test"); -getInnerHtml(); -var html = getOuterHtml(); -elm.getInnerHTML(); -elm.getOuterHTML(); +expect(element(by.id("myid")).getId()).toEqual("id"); +getRawId(); +var html = getRawId(); +elm.getRawId(); ``` diff --git a/index.js b/index.js index f45cbd8..b46746e 100644 --- a/index.js +++ b/index.js @@ -33,6 +33,7 @@ var useCountMethod = require('./lib/rules/use-count-method') var noBrowserDriver = require('./lib/rules/no-browser-driver') var validById = require('./lib/rules/valid-by-id') var validByTagName = require('./lib/rules/valid-by-tagname') +var noGetRawId = require('./lib/rules/no-get-raw-id') module.exports = { rules: { @@ -68,7 +69,8 @@ module.exports = { 'use-count-method': useCountMethod, 'no-browser-driver': noBrowserDriver, 'valid-by-id': validById, - 'valid-by-tagname': validByTagName + 'valid-by-tagname': validByTagName, + 'no-get-raw-id': noGetRawId }, configs: { recommended: { @@ -78,6 +80,7 @@ module.exports = { 'protractor/correct-chaining': 2, 'protractor/no-invalid-selectors': 2, 'protractor/no-array-finder-methods': 2, + 'protractor/no-get-raw-id': 2, 'protractor/valid-locator-type': 2, 'protractor/no-compound-classes': 2, 'protractor/missing-wait-message': 1, diff --git a/lib/is-element-finder.js b/lib/is-element-finder.js index 802e171..d81e5d0 100644 --- a/lib/is-element-finder.js +++ b/lib/is-element-finder.js @@ -6,10 +6,18 @@ * @fileoverview Utility function to determine if a node is an ElementFinder * @author Alexander Afanasyev */ + +var isElementArrayFinder = require('./is-element-array-finder') +var elementArrayFinderGetMethods = [ + 'get', + 'last', + 'first' +] + module.exports = function (node) { - // handling $ shortcut var callee = node.callee if (callee) { + // handling raw $ and element if (callee.name === '$' || callee.name === 'element') { return true } @@ -19,6 +27,11 @@ module.exports = function (node) { if (callee.property.name === '$' || callee.property.name === 'element') { return true } + + // got element finder from element array finder + if (elementArrayFinderGetMethods.indexOf(callee.property.name) > -1 && callee.object && isElementArrayFinder(callee.object)) { + return true + } } } diff --git a/lib/rules/no-get-raw-id.js b/lib/rules/no-get-raw-id.js index 55fbfbc..49bb702 100644 --- a/lib/rules/no-get-raw-id.js +++ b/lib/rules/no-get-raw-id.js @@ -1,9 +1,10 @@ 'use strict' /** - * @fileoverview Warn about using `getInnerHtml()` and `getOuterHtml()` methods + * @fileoverview Warn about using `getRawId()` method * @author Alexander Afanasyev */ +var isElementFinder = require('../is-element-finder') module.exports = { meta: { @@ -12,17 +13,14 @@ module.exports = { create: function (context) { return { - 'CallExpression': function (node) { - var object = node.callee.object - var property = node.callee.property + MemberExpression: function (node) { + var property = node.property - if (object && property) { - var isInnerHtml = property.name === 'getInnerHtml' - var isOuterHtml = property.name === 'getOuterHtml' - if (isInnerHtml || isOuterHtml) { + if (property && property.name === 'getRawId') { + if (node.object && isElementFinder(node.object)) { context.report({ - node: node, - message: 'Unexpected "' + property.name + '()"' + node: property, + message: 'Unexpected "' + property.name + '()". Use "getId()" instead' }) } } diff --git a/test/rules/no-get-raw-id.js b/test/rules/no-get-raw-id.js index af0ece7..de72274 100644 --- a/test/rules/no-get-raw-id.js +++ b/test/rules/no-get-raw-id.js @@ -1,65 +1,73 @@ 'use strict' -var rule = require('../../lib/rules/no-get-inner-outer-html') +var rule = require('../../lib/rules/no-get-raw-id') var RuleTester = require('eslint').RuleTester var eslintTester = new RuleTester() -eslintTester.run('no-get-inner-outer-html', rule, { +eslintTester.run('no-get-raw-id', rule, { valid: [ - 'expect(element(by.id("myid")).getText()).toEqual("test");', - 'getInnerHtml();', - 'var html = getOuterHtml();', - 'elm.getInnerHTML();', + 'expect(element(by.id("myid")).getId()).toEqual("id");', + 'getRawId();', + 'var html = getRawId();', + 'elm.getRawId();', 'elm.getOuterHTML();' ], invalid: [ { - code: 'expect(element(by.id("myid")).getInnerHtml()).toEqual("test");', + code: 'expect(element(by.id("myid")).getRawId()).toEqual("id");', errors: [ { - message: 'Unexpected "getInnerHtml()"' + message: 'Unexpected "getRawId()". Use "getId()" instead' } ] }, { - code: 'expect(element(by.id("myid")).getOuterHtml()).toEqual("test");', + code: 'element.all(by.css(".class")).get(1).getRawId();', errors: [ { - message: 'Unexpected "getOuterHtml()"' + message: 'Unexpected "getRawId()". Use "getId()" instead' } ] }, { - code: 'element.all(by.css(".class")).first().getOuterHtml();', + code: 'element.all(by.css(".class")).first().getRawId();', errors: [ { - message: 'Unexpected "getOuterHtml()"' + message: 'Unexpected "getRawId()". Use "getId()" instead' } ] }, { - code: 'element(by.id("id")).all(by.css(".class")).last().getInnerHtml();', + code: 'element(by.id("id")).all(by.css(".class")).last().getRawId();', errors: [ { - message: 'Unexpected "getInnerHtml()"' + message: 'Unexpected "getRawId()". Use "getId()" instead' } ] }, { - code: '$$(".class").first().getOuterHtml();', + code: 'element.all(by.css(".class")).first().$$(".myclass").last().getRawId();', errors: [ { - message: 'Unexpected "getOuterHtml()"' + message: 'Unexpected "getRawId()". Use "getId()" instead' } ] }, { - code: '$(".class").getInnerHtml().then(function (html) { console.log(html) });', + code: '$$(".class").first().getRawId();', errors: [ { - message: 'Unexpected "getInnerHtml()"' + message: 'Unexpected "getRawId()". Use "getId()" instead' + } + ] + }, + { + code: '$(".class").getRawId().then(function (id) { console.log(id) });', + errors: [ + { + message: 'Unexpected "getRawId()". Use "getId()" instead' } ] }