From 04687bd6ee12e569b31b10b66de259db42ab74b5 Mon Sep 17 00:00:00 2001 From: Alexander Afanasyev Date: Tue, 19 Jul 2016 13:46:00 -0400 Subject: [PATCH] feat(rules): add 'no-expect-in-po' rule --- README.md | 4 +- docs/rules/no-expect-in-po.md | 23 +++++++ index.js | 5 +- lib/rules/no-expect-in-po.js | 46 ++++++++++++++ package.json | 3 +- test/rules/no-expect-in-po.js | 112 ++++++++++++++++++++++++++++++++++ 6 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 docs/rules/no-expect-in-po.md create mode 100644 lib/rules/no-expect-in-po.js create mode 100644 test/rules/no-expect-in-po.js diff --git a/README.md b/README.md index 23d2bbb..b4fa119 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This plugin ships with a default configuration for each rule: Rule | Default | Options ----- | ------- | ------- +---- | ------- | --------- [missing-perform][] | 2 | [no-browser-pause][] | 2 | [missing-wait-message][] | 1 | @@ -51,6 +51,7 @@ Rule | Default | Options [no-get-in-it][] | 1 | [array-callback-return][] | 1 | [no-absolute-url][] | 1 | +[no-expect-in-po][] | 1 | requires plugin "settings" [by-css-shortcut][] | 0 | For example, the `missing-perform` rule is enabled by default and will cause @@ -84,6 +85,7 @@ See [configuring rules][] for more information. [array-callback-return]: docs/rules/array-callback-return.md [no-absolute-url]: docs/rules/no-absolute-url.md [by-css-shortcut]: docs/rules/by-css-shortcut.md +[no-expect-in-po]: docs/rules/no-expect-in-po.md [configuring rules]: http://eslint.org/docs/user-guide/configuring#configuring-rules ## Recommended configuration diff --git a/docs/rules/no-expect-in-po.md b/docs/rules/no-expect-in-po.md new file mode 100644 index 0000000..6a61cb3 --- /dev/null +++ b/docs/rules/no-expect-in-po.md @@ -0,0 +1,23 @@ +# Recommend against making assertions inside Page Objects + +This rule enforces the [Avoid using `expect()` in page objects](https://github.com/angular/protractor/blob/master/docs/style-guide.md#avoid-using-expect-in-page-objects) Protractor Style Guide recommendation. + +**Important:** This rule requires plugin `settings` to have the configured "glob"-style paths (see [`minimatch`](https://github.com/isaacs/minimatch) to learn more about the supported "glob" syntax) to distinguish Page Object files from others. + +Edit your ESLint config and add (this is example configuration): + + settings: { + "eslint-plugin-protractor": + paths: { + po: ["**/test/e2e/po/*.po.js"] + } + } + } + +If this setting is not present, the rule would be disabled. + +*Note: Because ESLint uses absolute paths and it is difficult to correctly locate base path of your project from within a plugin, so it is highly suggested to use complete paths to folders you want to disable to leverage the risk of targeting wrong directories and files.* + +## Rule details + +This rule would warn if it sees `expect()` function call inside a file that matches at least one of the patterns configured in paths/po array. diff --git a/index.js b/index.js index cf874c5..2987f8a 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,7 @@ var useFirstLast = require('./lib/rules/use-first-last') var noGetInIt = require('./lib/rules/no-get-in-it') var arrayCallbackReturn = require('./lib/rules/array-callback-return') var noAbsoluteURL = require('./lib/rules/no-absolute-url') +var noExpectInPO = require('./lib/rules/no-expect-in-po') module.exports = { rules: { @@ -34,7 +35,8 @@ module.exports = { 'use-first-last': useFirstLast, 'no-get-in-it': noGetInIt, 'array-callback-return': arrayCallbackReturn, - 'no-absolute-url': noAbsoluteURL + 'no-absolute-url': noAbsoluteURL, + 'no-expect-in-po': noExpectInPO }, configs: { recommended: { @@ -54,6 +56,7 @@ module.exports = { 'protractor/no-get-in-it': 1, 'protractor/array-callback-return': 1, 'protractor/no-absolute-url': 1, + 'protractor/no-expect-in-po': 1, 'protractor/by-css-shortcut': 0 }, globals: { diff --git a/lib/rules/no-expect-in-po.js b/lib/rules/no-expect-in-po.js new file mode 100644 index 0000000..9c4e7c5 --- /dev/null +++ b/lib/rules/no-expect-in-po.js @@ -0,0 +1,46 @@ +'use strict' + +/** + * @fileoverview Recommend against making assertions inside Page Objects + * @author Alexander Afanasyev + */ + +var PLUGIN_NAME = 'eslint-plugin-protractor' +var multimatch = require('multimatch') + +module.exports = { + meta: { + schema: [] + }, + + create: function (context) { + // do nothing if appropriate settings are not present + var settings = context.settings + if (!settings || !settings[PLUGIN_NAME] || !settings[PLUGIN_NAME].paths || !settings[PLUGIN_NAME].paths.po) { + return {} + } + + // get glob matches + var filename = context.getFilename() + var patterns = settings[PLUGIN_NAME].paths.po + var matches = multimatch(filename, patterns) + + // do nothing if a filename does not match pre-configured patterns + if (!matches || matches.length === 0) { + return {} + } + + return { + 'CallExpression': function (node) { + var callee = node.callee + + if (callee && callee.name === 'expect') { + context.report({ + node: node, + message: 'Unexpected "expect()" inside a Page Object' + }) + } + } + } + } +} diff --git a/package.json b/package.json index a54f533..09fb55b 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ } }, "dependencies": { - "css-selector-parser": "^1.1.0" + "css-selector-parser": "^1.1.0", + "multimatch": "^2.1.0" } } diff --git a/test/rules/no-expect-in-po.js b/test/rules/no-expect-in-po.js new file mode 100644 index 0000000..c0945e0 --- /dev/null +++ b/test/rules/no-expect-in-po.js @@ -0,0 +1,112 @@ +'use strict' + +var rule = require('../../lib/rules/no-expect-in-po') +var RuleTester = require('eslint').RuleTester +var eslintTester = new RuleTester() + +eslintTester.run('no-expect-in-po', rule, { + valid: [ + { + code: 'var test = "bar"' + }, + + { + code: 'expect(1).toEqual(1);' + }, + + { + code: 'expect(2).toEqual(2);', + 'eslint-plugin-protractor': { + settings: { + paths: { + po: ['*.po.js'] + } + } + }, + filename: 'test.spec.js' + }, + + { + code: 'expect(3).toEqual(3);', + 'eslint-plugin-protractor': { + settings: { + paths: { + po: ['*.somethingelse.js'] + } + } + }, + filename: 'test.po.js' + }, + + { + code: 'expect(4).toEqual(4);', + 'eslint-plugin-protractor': { + settings: { + paths: { + po: [] + } + } + }, + filename: 'test.po.js' + }, + + { + code: 'expect(5).toEqual(5);', + 'eslint-plugin-protractor': { + settings: { + paths: { + po: ['*.somethingelse1.js', '*.somethingelse2.js'] + } + } + }, + filename: 'test.po.js' + } + ], + + invalid: [ + { + code: 'expect(-1).toEqual(-1);', + settings: { + 'eslint-plugin-protractor': { + paths: { + po: ['**/po/*.po.js'] + } + } + }, + filename: '/var/app/test/e2e/po/test.po.js', + errors: [{ + message: 'Unexpected "expect()" inside a Page Object' + }] + }, + + { + code: 'expect(-2).toEqual(-2);', + settings: { + 'eslint-plugin-protractor': { + paths: { + po: ['**/*.js'] + } + } + }, + filename: '/var/app/test/e2e/po/test.po.js', + errors: [{ + message: 'Unexpected "expect()" inside a Page Object' + }] + }, + + { + code: 'expect(-3).toEqual(-3);', + settings: { + 'eslint-plugin-protractor': { + paths: { + po: ['**/*.somethingelse1.js', '**/*.po.js', '**/*.somethingelse2.js'] + } + } + }, + filename: '/var/app/test/e2e/po/test.po.js', + errors: [{ + message: 'Unexpected "expect()" inside a Page Object' + }] + } + ] +})