Skip to content

Commit 04687bd

Browse files
committed
feat(rules): add 'no-expect-in-po' rule
1 parent 28d5d5b commit 04687bd

File tree

6 files changed

+190
-3
lines changed

6 files changed

+190
-3
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
This plugin ships with a default configuration for each rule:
3636

3737
Rule | Default | Options
38-
---- | ------- | -------
38+
---- | ------- | ---------
3939
[missing-perform][] | 2 |
4040
[no-browser-pause][] | 2 |
4141
[missing-wait-message][] | 1 |
@@ -51,6 +51,7 @@ Rule | Default | Options
5151
[no-get-in-it][] | 1 |
5252
[array-callback-return][] | 1 |
5353
[no-absolute-url][] | 1 |
54+
[no-expect-in-po][] | 1 | requires plugin "settings"
5455
[by-css-shortcut][] | 0 |
5556

5657
For example, the `missing-perform` rule is enabled by default and will cause
@@ -84,6 +85,7 @@ See [configuring rules][] for more information.
8485
[array-callback-return]: docs/rules/array-callback-return.md
8586
[no-absolute-url]: docs/rules/no-absolute-url.md
8687
[by-css-shortcut]: docs/rules/by-css-shortcut.md
88+
[no-expect-in-po]: docs/rules/no-expect-in-po.md
8789
[configuring rules]: http://eslint.org/docs/user-guide/configuring#configuring-rules
8890

8991
## Recommended configuration

docs/rules/no-expect-in-po.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Recommend against making assertions inside Page Objects
2+
3+
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.
4+
5+
**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.
6+
7+
Edit your ESLint config and add (this is example configuration):
8+
9+
settings: {
10+
"eslint-plugin-protractor":
11+
paths: {
12+
po: ["**/test/e2e/po/*.po.js"]
13+
}
14+
}
15+
}
16+
17+
If this setting is not present, the rule would be disabled.
18+
19+
*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.*
20+
21+
## Rule details
22+
23+
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.

index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var useFirstLast = require('./lib/rules/use-first-last')
1616
var noGetInIt = require('./lib/rules/no-get-in-it')
1717
var arrayCallbackReturn = require('./lib/rules/array-callback-return')
1818
var noAbsoluteURL = require('./lib/rules/no-absolute-url')
19+
var noExpectInPO = require('./lib/rules/no-expect-in-po')
1920

2021
module.exports = {
2122
rules: {
@@ -34,7 +35,8 @@ module.exports = {
3435
'use-first-last': useFirstLast,
3536
'no-get-in-it': noGetInIt,
3637
'array-callback-return': arrayCallbackReturn,
37-
'no-absolute-url': noAbsoluteURL
38+
'no-absolute-url': noAbsoluteURL,
39+
'no-expect-in-po': noExpectInPO
3840
},
3941
configs: {
4042
recommended: {
@@ -54,6 +56,7 @@ module.exports = {
5456
'protractor/no-get-in-it': 1,
5557
'protractor/array-callback-return': 1,
5658
'protractor/no-absolute-url': 1,
59+
'protractor/no-expect-in-po': 1,
5760
'protractor/by-css-shortcut': 0
5861
},
5962
globals: {

lib/rules/no-expect-in-po.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict'
2+
3+
/**
4+
* @fileoverview Recommend against making assertions inside Page Objects
5+
* @author Alexander Afanasyev
6+
*/
7+
8+
var PLUGIN_NAME = 'eslint-plugin-protractor'
9+
var multimatch = require('multimatch')
10+
11+
module.exports = {
12+
meta: {
13+
schema: []
14+
},
15+
16+
create: function (context) {
17+
// do nothing if appropriate settings are not present
18+
var settings = context.settings
19+
if (!settings || !settings[PLUGIN_NAME] || !settings[PLUGIN_NAME].paths || !settings[PLUGIN_NAME].paths.po) {
20+
return {}
21+
}
22+
23+
// get glob matches
24+
var filename = context.getFilename()
25+
var patterns = settings[PLUGIN_NAME].paths.po
26+
var matches = multimatch(filename, patterns)
27+
28+
// do nothing if a filename does not match pre-configured patterns
29+
if (!matches || matches.length === 0) {
30+
return {}
31+
}
32+
33+
return {
34+
'CallExpression': function (node) {
35+
var callee = node.callee
36+
37+
if (callee && callee.name === 'expect') {
38+
context.report({
39+
node: node,
40+
message: 'Unexpected "expect()" inside a Page Object'
41+
})
42+
}
43+
}
44+
}
45+
}
46+
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
}
6464
},
6565
"dependencies": {
66-
"css-selector-parser": "^1.1.0"
66+
"css-selector-parser": "^1.1.0",
67+
"multimatch": "^2.1.0"
6768
}
6869
}

test/rules/no-expect-in-po.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
'use strict'
2+
3+
var rule = require('../../lib/rules/no-expect-in-po')
4+
var RuleTester = require('eslint').RuleTester
5+
var eslintTester = new RuleTester()
6+
7+
eslintTester.run('no-expect-in-po', rule, {
8+
valid: [
9+
{
10+
code: 'var test = "bar"'
11+
},
12+
13+
{
14+
code: 'expect(1).toEqual(1);'
15+
},
16+
17+
{
18+
code: 'expect(2).toEqual(2);',
19+
'eslint-plugin-protractor': {
20+
settings: {
21+
paths: {
22+
po: ['*.po.js']
23+
}
24+
}
25+
},
26+
filename: 'test.spec.js'
27+
},
28+
29+
{
30+
code: 'expect(3).toEqual(3);',
31+
'eslint-plugin-protractor': {
32+
settings: {
33+
paths: {
34+
po: ['*.somethingelse.js']
35+
}
36+
}
37+
},
38+
filename: 'test.po.js'
39+
},
40+
41+
{
42+
code: 'expect(4).toEqual(4);',
43+
'eslint-plugin-protractor': {
44+
settings: {
45+
paths: {
46+
po: []
47+
}
48+
}
49+
},
50+
filename: 'test.po.js'
51+
},
52+
53+
{
54+
code: 'expect(5).toEqual(5);',
55+
'eslint-plugin-protractor': {
56+
settings: {
57+
paths: {
58+
po: ['*.somethingelse1.js', '*.somethingelse2.js']
59+
}
60+
}
61+
},
62+
filename: 'test.po.js'
63+
}
64+
],
65+
66+
invalid: [
67+
{
68+
code: 'expect(-1).toEqual(-1);',
69+
settings: {
70+
'eslint-plugin-protractor': {
71+
paths: {
72+
po: ['**/po/*.po.js']
73+
}
74+
}
75+
},
76+
filename: '/var/app/test/e2e/po/test.po.js',
77+
errors: [{
78+
message: 'Unexpected "expect()" inside a Page Object'
79+
}]
80+
},
81+
82+
{
83+
code: 'expect(-2).toEqual(-2);',
84+
settings: {
85+
'eslint-plugin-protractor': {
86+
paths: {
87+
po: ['**/*.js']
88+
}
89+
}
90+
},
91+
filename: '/var/app/test/e2e/po/test.po.js',
92+
errors: [{
93+
message: 'Unexpected "expect()" inside a Page Object'
94+
}]
95+
},
96+
97+
{
98+
code: 'expect(-3).toEqual(-3);',
99+
settings: {
100+
'eslint-plugin-protractor': {
101+
paths: {
102+
po: ['**/*.somethingelse1.js', '**/*.po.js', '**/*.somethingelse2.js']
103+
}
104+
}
105+
},
106+
filename: '/var/app/test/e2e/po/test.po.js',
107+
errors: [{
108+
message: 'Unexpected "expect()" inside a Page Object'
109+
}]
110+
}
111+
]
112+
})

0 commit comments

Comments
 (0)