eslint-plugin-playwright 2.3.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +12 -13
- package/README.md +4 -4
- package/dist/index.cjs +34 -6
- package/package.json +29 -2
package/LICENSE
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2024
|
|
3
|
+
Copyright (c) 2024 Mark Skelton
|
|
4
4
|
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
11
|
|
|
12
12
|
The above copyright notice and this permission notice shall be included in all
|
|
13
13
|
copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
SOFTWARE.
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -38,19 +38,19 @@ file patterns.
|
|
|
38
38
|
(**eslint.config.js**)
|
|
39
39
|
|
|
40
40
|
```javascript
|
|
41
|
+
import { defineConfig } from '@eslint/config'
|
|
41
42
|
import playwright from 'eslint-plugin-playwright'
|
|
42
43
|
|
|
43
|
-
export default [
|
|
44
|
+
export default defineConfig([
|
|
44
45
|
{
|
|
45
|
-
...playwright.configs['flat/recommended'],
|
|
46
46
|
files: ['tests/**'],
|
|
47
|
+
extends: [playwright.configs['flat/recommended']],
|
|
47
48
|
rules: {
|
|
48
|
-
...playwright.configs['flat/recommended'].rules,
|
|
49
49
|
// Customize Playwright rules
|
|
50
50
|
// ...
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
|
-
]
|
|
53
|
+
])
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
[Legacy config](https://eslint.org/docs/latest/use/configure/configuration-files)
|
package/dist/index.cjs
CHANGED
|
@@ -435,8 +435,12 @@ var expect_expect_default = createRule({
|
|
|
435
435
|
create(context) {
|
|
436
436
|
const options = {
|
|
437
437
|
assertFunctionNames: [],
|
|
438
|
+
assertFunctionPatterns: [],
|
|
438
439
|
...context.options?.[0] ?? {}
|
|
439
440
|
};
|
|
441
|
+
const patterns = options.assertFunctionPatterns.map(
|
|
442
|
+
(pattern) => new RegExp(pattern)
|
|
443
|
+
);
|
|
440
444
|
const unchecked = [];
|
|
441
445
|
function checkExpressions(nodes) {
|
|
442
446
|
for (const node of nodes) {
|
|
@@ -447,12 +451,21 @@ var expect_expect_default = createRule({
|
|
|
447
451
|
}
|
|
448
452
|
}
|
|
449
453
|
}
|
|
454
|
+
function matches(node) {
|
|
455
|
+
if (options.assertFunctionNames.some((name) => dig(node.callee, name))) {
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
if (patterns.some((pattern) => dig(node.callee, pattern))) {
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
450
463
|
return {
|
|
451
464
|
CallExpression(node) {
|
|
452
465
|
const call = parseFnCall(context, node);
|
|
453
466
|
if (call?.type === "test") {
|
|
454
467
|
unchecked.push(node);
|
|
455
|
-
} else if (call?.type === "expect" ||
|
|
468
|
+
} else if (call?.type === "expect" || matches(node)) {
|
|
456
469
|
const ancestors = context.sourceCode.getAncestors(node);
|
|
457
470
|
checkExpressions(ancestors);
|
|
458
471
|
}
|
|
@@ -481,6 +494,10 @@ var expect_expect_default = createRule({
|
|
|
481
494
|
assertFunctionNames: {
|
|
482
495
|
items: [{ type: "string" }],
|
|
483
496
|
type: "array"
|
|
497
|
+
},
|
|
498
|
+
assertFunctionPatterns: {
|
|
499
|
+
items: [{ type: "string" }],
|
|
500
|
+
type: "array"
|
|
484
501
|
}
|
|
485
502
|
},
|
|
486
503
|
type: "object"
|
|
@@ -693,14 +710,17 @@ var missing_playwright_await_default = createRule({
|
|
|
693
710
|
// Add any custom matchers to the set
|
|
694
711
|
...options.customMatchers || []
|
|
695
712
|
]);
|
|
696
|
-
function checkValidity(node) {
|
|
713
|
+
function checkValidity(node, visited) {
|
|
697
714
|
const parent = getParent(node);
|
|
698
715
|
if (!parent)
|
|
699
716
|
return false;
|
|
717
|
+
if (visited.has(parent))
|
|
718
|
+
return false;
|
|
719
|
+
visited.add(parent);
|
|
700
720
|
if (validTypes.has(parent.type))
|
|
701
721
|
return true;
|
|
702
722
|
if (parent.type === "ArrayExpression") {
|
|
703
|
-
return checkValidity(parent);
|
|
723
|
+
return checkValidity(parent, visited);
|
|
704
724
|
}
|
|
705
725
|
if (parent.type === "CallExpression" && parent.callee.type === "MemberExpression" && isIdentifier(parent.callee.object, "Promise") && isIdentifier(parent.callee.property, "all")) {
|
|
706
726
|
return true;
|
|
@@ -709,9 +729,11 @@ var missing_playwright_await_default = createRule({
|
|
|
709
729
|
const scope = context.sourceCode.getScope(parent.parent);
|
|
710
730
|
for (const ref of scope.references) {
|
|
711
731
|
const refParent = ref.identifier.parent;
|
|
732
|
+
if (visited.has(refParent))
|
|
733
|
+
continue;
|
|
712
734
|
if (validTypes.has(refParent.type))
|
|
713
735
|
return true;
|
|
714
|
-
if (checkValidity(refParent))
|
|
736
|
+
if (checkValidity(refParent, visited))
|
|
715
737
|
return true;
|
|
716
738
|
}
|
|
717
739
|
}
|
|
@@ -723,7 +745,7 @@ var missing_playwright_await_default = createRule({
|
|
|
723
745
|
if (call?.type !== "step" && call?.type !== "expect")
|
|
724
746
|
return;
|
|
725
747
|
const result = getCallType(call, awaitableMatchers);
|
|
726
|
-
const isValid = result ? checkValidity(node) : false;
|
|
748
|
+
const isValid = result ? checkValidity(node, /* @__PURE__ */ new Set()) : false;
|
|
727
749
|
if (result && !isValid) {
|
|
728
750
|
context.report({
|
|
729
751
|
data: result.data,
|
|
@@ -899,6 +921,9 @@ var no_conditional_expect_default = createRule({
|
|
|
899
921
|
var no_conditional_in_test_default = createRule({
|
|
900
922
|
create(context) {
|
|
901
923
|
function checkConditional(node) {
|
|
924
|
+
if (node.type === "LogicalExpression" && node.operator === "??") {
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
902
927
|
const call = findParent(node, "CallExpression");
|
|
903
928
|
if (!call)
|
|
904
929
|
return;
|
|
@@ -1702,13 +1727,16 @@ var no_standalone_expect_default = createRule({
|
|
|
1702
1727
|
if (call?.type === "hook") {
|
|
1703
1728
|
callStack.push("hook");
|
|
1704
1729
|
}
|
|
1730
|
+
if (node.callee.type === "MemberExpression" && isPropertyAccessor(node.callee, "extend")) {
|
|
1731
|
+
callStack.push("fixture");
|
|
1732
|
+
}
|
|
1705
1733
|
if (node.callee.type === "TaggedTemplateExpression") {
|
|
1706
1734
|
callStack.push("template");
|
|
1707
1735
|
}
|
|
1708
1736
|
},
|
|
1709
1737
|
"CallExpression:exit"(node) {
|
|
1710
1738
|
const top = callStack.at(-1);
|
|
1711
|
-
if (top === "test" && isTypeOfFnCall(context, node, ["test"]) && node.callee.type !== "MemberExpression" || top === "template" && node.callee.type === "TaggedTemplateExpression") {
|
|
1739
|
+
if (top === "test" && isTypeOfFnCall(context, node, ["test"]) && node.callee.type !== "MemberExpression" || top === "template" && node.callee.type === "TaggedTemplateExpression" || top === "fixture" && node.callee.type === "MemberExpression" && isPropertyAccessor(node.callee, "extend")) {
|
|
1712
1740
|
callStack.pop();
|
|
1713
1741
|
}
|
|
1714
1742
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-playwright",
|
|
3
3
|
"description": "ESLint plugin for Playwright testing.",
|
|
4
|
-
"version": "2.
|
|
5
|
-
"repository":
|
|
4
|
+
"version": "2.4.1",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/mskelton/eslint-plugin-playwright.git"
|
|
8
|
+
},
|
|
6
9
|
"author": "Mark Skelton <mark@mskelton.dev>",
|
|
10
|
+
"packageManager": "pnpm@8.12.0",
|
|
7
11
|
"contributors": [
|
|
8
12
|
"Max Schmitt <max@schmitt.mx>"
|
|
9
13
|
],
|
|
@@ -26,10 +30,33 @@
|
|
|
26
30
|
"index.cjs",
|
|
27
31
|
"index.d.ts"
|
|
28
32
|
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup src/index.ts --format cjs --out-dir dist",
|
|
35
|
+
"lint": "eslint .",
|
|
36
|
+
"format": "prettier --write .",
|
|
37
|
+
"format:check": "prettier --check .",
|
|
38
|
+
"test": "vitest --run --hideSkippedTests",
|
|
39
|
+
"test:watch": "vitest --reporter=dot --run",
|
|
40
|
+
"ts": "tsc --noEmit"
|
|
41
|
+
},
|
|
29
42
|
"peerDependencies": {
|
|
30
43
|
"eslint": ">=8.40.0"
|
|
31
44
|
},
|
|
32
45
|
"dependencies": {
|
|
33
46
|
"globals": "^16.4.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@mskelton/eslint-config": "^9.0.1",
|
|
50
|
+
"@types/estree": "^1.0.6",
|
|
51
|
+
"@types/node": "^20.11.17",
|
|
52
|
+
"@typescript-eslint/parser": "^8.11.0",
|
|
53
|
+
"dedent": "^1.5.1",
|
|
54
|
+
"eslint": "^9.13.0",
|
|
55
|
+
"prettier": "^3.0.3",
|
|
56
|
+
"prettier-plugin-jsdoc": "^1.3.0",
|
|
57
|
+
"semantic-release": "^25.0.2",
|
|
58
|
+
"tsup": "^8.0.1",
|
|
59
|
+
"typescript": "^5.2.2",
|
|
60
|
+
"vitest": "^1.6.1"
|
|
34
61
|
}
|
|
35
62
|
}
|