eslint-plugin-playwright 2.2.0 → 2.2.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/README.md +3 -1
- package/dist/index.cjs +220 -29
- package/package.json +1 -29
package/README.md
CHANGED
|
@@ -139,11 +139,12 @@ CLI option\
|
|
|
139
139
|
| [no-raw-locators](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-raw-locators.md) | Disallow using raw locators | | | |
|
|
140
140
|
| [no-restricted-matchers](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-restricted-matchers.md) | Disallow specific matchers & modifiers | | | |
|
|
141
141
|
| [no-skipped-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-skipped-test.md) | Disallow usage of the `.skip` annotation | ✅ | | 💡 |
|
|
142
|
-
| [no-slowed-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-slowed-test.md) | Disallow usage of the `.slow` annotation |
|
|
142
|
+
| [no-slowed-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-slowed-test.md) | Disallow usage of the `.slow` annotation | | | 💡 |
|
|
143
143
|
| [no-standalone-expect](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-standalone-expect.md) | Disallow using expect outside of `test` blocks | ✅ | | |
|
|
144
144
|
| [no-unsafe-references](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-unsafe-references.md) | Prevent unsafe variable references in `page.evaluate()` | ✅ | 🔧 | |
|
|
145
145
|
| [no-useless-await](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-useless-await.md) | Disallow unnecessary `await`s for Playwright methods | ✅ | 🔧 | |
|
|
146
146
|
| [no-useless-not](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-useless-not.md) | Disallow usage of `not` matchers when a specific matcher exists | ✅ | 🔧 | |
|
|
147
|
+
| [no-wait-for-navigation](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-navigation.md) | Disallow usage of `page.waitForNavigation()` | ✅ | | 💡 |
|
|
147
148
|
| [no-wait-for-selector](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-selector.md) | Disallow usage of `page.waitForSelector()` | ✅ | | 💡 |
|
|
148
149
|
| [no-wait-for-timeout](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-timeout.md) | Disallow usage of `page.waitForTimeout()` | ✅ | | 💡 |
|
|
149
150
|
| [prefer-comparison-matcher](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | 🔧 | |
|
|
@@ -167,3 +168,4 @@ CLI option\
|
|
|
167
168
|
| [valid-expect-in-promise](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-expect-in-promise.md) | Require promises that have expectations in their chain to be valid | ✅ | | |
|
|
168
169
|
| [valid-expect](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-expect.md) | Enforce valid `expect()` usage | ✅ | | |
|
|
169
170
|
| [valid-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-title.md) | Enforce valid titles | ✅ | 🔧 | |
|
|
171
|
+
| [valid-test-tags](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-test-tags.md) | Enforce valid tag format in test blocks | ✅ | | |
|
package/dist/index.cjs
CHANGED
|
@@ -689,7 +689,8 @@ var playwrightTestMatchers = [
|
|
|
689
689
|
"toHaveTitle",
|
|
690
690
|
"toHaveURL",
|
|
691
691
|
"toHaveValue",
|
|
692
|
-
"toHaveValues"
|
|
692
|
+
"toHaveValues",
|
|
693
|
+
"toContainClass"
|
|
693
694
|
];
|
|
694
695
|
function getReportNode(node) {
|
|
695
696
|
const parent = getParent(node);
|
|
@@ -929,7 +930,17 @@ var no_conditional_in_test_default = createRule({
|
|
|
929
930
|
if (!call)
|
|
930
931
|
return;
|
|
931
932
|
if (isTypeOfFnCall(context, call, ["test", "step"])) {
|
|
932
|
-
|
|
933
|
+
const testFunction = call.arguments[call.arguments.length - 1];
|
|
934
|
+
const functionBody = findParent(node, "BlockStatement");
|
|
935
|
+
if (!functionBody)
|
|
936
|
+
return;
|
|
937
|
+
let currentParent = functionBody.parent;
|
|
938
|
+
while (currentParent && currentParent !== testFunction) {
|
|
939
|
+
currentParent = currentParent.parent;
|
|
940
|
+
}
|
|
941
|
+
if (currentParent === testFunction) {
|
|
942
|
+
context.report({ messageId: "conditionalInTest", node });
|
|
943
|
+
}
|
|
933
944
|
}
|
|
934
945
|
}
|
|
935
946
|
return {
|
|
@@ -1429,7 +1440,7 @@ var no_raw_locators_default = createRule({
|
|
|
1429
1440
|
}
|
|
1430
1441
|
return {
|
|
1431
1442
|
CallExpression(node) {
|
|
1432
|
-
if (node.callee.type !== "MemberExpression")
|
|
1443
|
+
if (node.callee.type !== "MemberExpression" || node.arguments[0]?.type === "Identifier")
|
|
1433
1444
|
return;
|
|
1434
1445
|
const method = getStringValue(node.callee.property);
|
|
1435
1446
|
const arg = getStringValue(node.arguments[0]);
|
|
@@ -1540,7 +1551,7 @@ var no_skipped_test_default = createRule({
|
|
|
1540
1551
|
if (!skipNode)
|
|
1541
1552
|
return;
|
|
1542
1553
|
const isStandalone = call.type === "config";
|
|
1543
|
-
if (isStandalone && allowConditional) {
|
|
1554
|
+
if (isStandalone && allowConditional && (node.arguments.length !== 0 || findParent(node, "BlockStatement")?.parent?.type === "IfStatement")) {
|
|
1544
1555
|
return;
|
|
1545
1556
|
}
|
|
1546
1557
|
context.report({
|
|
@@ -1604,7 +1615,7 @@ var no_slowed_test_default = createRule({
|
|
|
1604
1615
|
if (!slowNode)
|
|
1605
1616
|
return;
|
|
1606
1617
|
const isStandalone = call.type === "config";
|
|
1607
|
-
if (isStandalone && allowConditional) {
|
|
1618
|
+
if (isStandalone && allowConditional && (node.arguments.length !== 0 || findParent(node, "BlockStatement")?.parent?.type === "IfStatement")) {
|
|
1608
1619
|
return;
|
|
1609
1620
|
}
|
|
1610
1621
|
context.report({
|
|
@@ -1629,7 +1640,7 @@ var no_slowed_test_default = createRule({
|
|
|
1629
1640
|
docs: {
|
|
1630
1641
|
category: "Best Practices",
|
|
1631
1642
|
description: "Prevent usage of the `.slow()` slow test annotation.",
|
|
1632
|
-
recommended:
|
|
1643
|
+
recommended: false,
|
|
1633
1644
|
url: "https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-slowed-test.md"
|
|
1634
1645
|
},
|
|
1635
1646
|
hasSuggestions: true,
|
|
@@ -1795,7 +1806,7 @@ var no_unsafe_references_default = createRule({
|
|
|
1795
1806
|
create(context) {
|
|
1796
1807
|
return {
|
|
1797
1808
|
CallExpression(node) {
|
|
1798
|
-
if (!isPageMethod(node, "evaluate"))
|
|
1809
|
+
if (!isPageMethod(node, "evaluate") && !isPageMethod(node, "addInitScript"))
|
|
1799
1810
|
return;
|
|
1800
1811
|
const [fn] = node.arguments;
|
|
1801
1812
|
if (!fn || !isFunction(fn))
|
|
@@ -1806,8 +1817,9 @@ var no_unsafe_references_default = createRule({
|
|
|
1806
1817
|
const parent = getParent(ref.identifier);
|
|
1807
1818
|
return parent?.type !== "TSTypeReference";
|
|
1808
1819
|
}).filter((ref) => allRefs.has(ref.identifier.name)).forEach((ref, i, arr) => {
|
|
1820
|
+
const methodName = isPageMethod(node, "evaluate") ? "evaluate" : "addInitScript";
|
|
1809
1821
|
const descriptor = {
|
|
1810
|
-
data: { variable: ref.identifier.name },
|
|
1822
|
+
data: { method: methodName, variable: ref.identifier.name },
|
|
1811
1823
|
messageId: "noUnsafeReference",
|
|
1812
1824
|
node: ref.identifier
|
|
1813
1825
|
};
|
|
@@ -1832,13 +1844,13 @@ var no_unsafe_references_default = createRule({
|
|
|
1832
1844
|
meta: {
|
|
1833
1845
|
docs: {
|
|
1834
1846
|
category: "Possible Errors",
|
|
1835
|
-
description: "Prevent unsafe variable references in page.evaluate()",
|
|
1847
|
+
description: "Prevent unsafe variable references in page.evaluate() and page.addInitScript()",
|
|
1836
1848
|
recommended: true,
|
|
1837
1849
|
url: "https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-unsafe-references.md"
|
|
1838
1850
|
},
|
|
1839
1851
|
fixable: "code",
|
|
1840
1852
|
messages: {
|
|
1841
|
-
noUnsafeReference: 'Unsafe reference to variable "{{ variable }}" in page.
|
|
1853
|
+
noUnsafeReference: 'Unsafe reference to variable "{{ variable }}" in page.{{ method }}()'
|
|
1842
1854
|
},
|
|
1843
1855
|
type: "problem"
|
|
1844
1856
|
}
|
|
@@ -2065,6 +2077,44 @@ var no_useless_not_default = createRule({
|
|
|
2065
2077
|
}
|
|
2066
2078
|
});
|
|
2067
2079
|
|
|
2080
|
+
// src/rules/no-wait-for-navigation.ts
|
|
2081
|
+
var no_wait_for_navigation_default = createRule({
|
|
2082
|
+
create(context) {
|
|
2083
|
+
return {
|
|
2084
|
+
CallExpression(node) {
|
|
2085
|
+
if (isPageMethod(node, "waitForNavigation")) {
|
|
2086
|
+
context.report({
|
|
2087
|
+
messageId: "noWaitForNavigation",
|
|
2088
|
+
node,
|
|
2089
|
+
suggest: [
|
|
2090
|
+
{
|
|
2091
|
+
fix: (fixer) => fixer.remove(
|
|
2092
|
+
node.parent && node.parent.type !== "AwaitExpression" && node.parent.type !== "VariableDeclarator" ? node.parent : node.parent.parent
|
|
2093
|
+
),
|
|
2094
|
+
messageId: "removeWaitForNavigation"
|
|
2095
|
+
}
|
|
2096
|
+
]
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
};
|
|
2101
|
+
},
|
|
2102
|
+
meta: {
|
|
2103
|
+
docs: {
|
|
2104
|
+
category: "Possible Errors",
|
|
2105
|
+
description: "Prevent usage of page.waitForNavigation()",
|
|
2106
|
+
recommended: true,
|
|
2107
|
+
url: "https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-navigation.md"
|
|
2108
|
+
},
|
|
2109
|
+
hasSuggestions: true,
|
|
2110
|
+
messages: {
|
|
2111
|
+
noWaitForNavigation: "Unexpected use of page.waitForNavigation().",
|
|
2112
|
+
removeWaitForNavigation: "Remove the page.waitForNavigation() method."
|
|
2113
|
+
},
|
|
2114
|
+
type: "suggestion"
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
2117
|
+
|
|
2068
2118
|
// src/rules/no-wait-for-selector.ts
|
|
2069
2119
|
var no_wait_for_selector_default = createRule({
|
|
2070
2120
|
create(context) {
|
|
@@ -3016,45 +3066,45 @@ var prefer_web_first_assertions_default = createRule({
|
|
|
3016
3066
|
create(context) {
|
|
3017
3067
|
return {
|
|
3018
3068
|
CallExpression(node) {
|
|
3019
|
-
const
|
|
3020
|
-
if (
|
|
3069
|
+
const fnCall = parseFnCall(context, node);
|
|
3070
|
+
if (fnCall?.type !== "expect")
|
|
3021
3071
|
return;
|
|
3022
|
-
const expect = findParent(
|
|
3072
|
+
const expect = findParent(fnCall.head.node, "CallExpression");
|
|
3023
3073
|
if (!expect)
|
|
3024
3074
|
return;
|
|
3025
|
-
const arg = dereference(context,
|
|
3026
|
-
if (!arg
|
|
3075
|
+
const arg = dereference(context, fnCall.args[0]);
|
|
3076
|
+
if (!arg)
|
|
3077
|
+
return;
|
|
3078
|
+
const call = arg.type === "AwaitExpression" ? arg.argument : arg;
|
|
3079
|
+
if (call.type !== "CallExpression" || call.callee.type !== "MemberExpression") {
|
|
3027
3080
|
return;
|
|
3028
3081
|
}
|
|
3029
|
-
if (!supportedMatchers.has(
|
|
3082
|
+
if (!supportedMatchers.has(fnCall.matcherName))
|
|
3030
3083
|
return;
|
|
3031
|
-
const method = getStringValue(
|
|
3084
|
+
const method = getStringValue(call.callee.property);
|
|
3032
3085
|
const methodConfig = methods3[method];
|
|
3033
3086
|
if (!methodConfig)
|
|
3034
3087
|
return;
|
|
3035
|
-
const notModifier =
|
|
3088
|
+
const notModifier = fnCall.modifiers.find(
|
|
3036
3089
|
(mod) => getStringValue(mod) === "not"
|
|
3037
3090
|
);
|
|
3038
|
-
const isFalsy = methodConfig.type === "boolean" && (!!
|
|
3091
|
+
const isFalsy = methodConfig.type === "boolean" && (!!fnCall.matcherArgs.length && isBooleanLiteral(fnCall.matcherArgs[0], false) || fnCall.matcherName === "toBeFalsy");
|
|
3039
3092
|
const isInverse = methodConfig.inverse ? notModifier || isFalsy : notModifier && isFalsy;
|
|
3040
3093
|
const newMatcher = +!!notModifier ^ +isFalsy && methodConfig.inverse || methodConfig.matcher;
|
|
3041
|
-
const { callee } =
|
|
3094
|
+
const { callee } = call;
|
|
3042
3095
|
context.report({
|
|
3043
3096
|
data: {
|
|
3044
3097
|
matcher: newMatcher,
|
|
3045
3098
|
method
|
|
3046
3099
|
},
|
|
3047
3100
|
fix: (fixer) => {
|
|
3048
|
-
const methodArgs =
|
|
3101
|
+
const methodArgs = call.type === "CallExpression" ? call.arguments : [];
|
|
3049
3102
|
const methodEnd = methodArgs.length ? methodArgs.at(-1).range[1] + 1 : callee.property.range[1] + 2;
|
|
3050
3103
|
const fixes = [
|
|
3051
3104
|
// Add await to the expect call
|
|
3052
3105
|
fixer.insertTextBefore(expect, "await "),
|
|
3053
3106
|
// Remove the await keyword
|
|
3054
|
-
fixer.replaceTextRange(
|
|
3055
|
-
[arg.range[0], arg.argument.range[0]],
|
|
3056
|
-
""
|
|
3057
|
-
),
|
|
3107
|
+
fixer.replaceTextRange([arg.range[0], call.range[0]], ""),
|
|
3058
3108
|
// Remove the old Playwright method and any arguments
|
|
3059
3109
|
fixer.replaceTextRange(
|
|
3060
3110
|
[callee.property.range[0] - 1, methodEnd],
|
|
@@ -3066,10 +3116,10 @@ var prefer_web_first_assertions_default = createRule({
|
|
|
3066
3116
|
fixes.push(fixer.removeRange([notRange[0], notRange[1] + 1]));
|
|
3067
3117
|
}
|
|
3068
3118
|
if (!methodConfig.inverse && !notModifier && isFalsy) {
|
|
3069
|
-
fixes.push(fixer.insertTextBefore(
|
|
3119
|
+
fixes.push(fixer.insertTextBefore(fnCall.matcher, "not."));
|
|
3070
3120
|
}
|
|
3071
|
-
fixes.push(fixer.replaceText(
|
|
3072
|
-
const [matcherArg] =
|
|
3121
|
+
fixes.push(fixer.replaceText(fnCall.matcher, newMatcher));
|
|
3122
|
+
const [matcherArg] = fnCall.matcherArgs ?? [];
|
|
3073
3123
|
if (matcherArg && isBooleanLiteral(matcherArg)) {
|
|
3074
3124
|
fixes.push(fixer.remove(matcherArg));
|
|
3075
3125
|
} else if (methodConfig.prop && matcherArg) {
|
|
@@ -3082,7 +3132,7 @@ var prefer_web_first_assertions_default = createRule({
|
|
|
3082
3132
|
(arg2) => !isBooleanLiteral(arg2)
|
|
3083
3133
|
).length;
|
|
3084
3134
|
if (methodArgs) {
|
|
3085
|
-
const range =
|
|
3135
|
+
const range = fnCall.matcher.range;
|
|
3086
3136
|
const stringArgs = methodArgs.map((arg2) => getRawValue(arg2)).concat(hasOtherArgs ? "" : []).join(", ");
|
|
3087
3137
|
fixes.push(
|
|
3088
3138
|
fixer.insertTextAfterRange(
|
|
@@ -3789,6 +3839,144 @@ var valid_expect_in_promise_default = createRule({
|
|
|
3789
3839
|
}
|
|
3790
3840
|
});
|
|
3791
3841
|
|
|
3842
|
+
// src/rules/valid-test-tags.ts
|
|
3843
|
+
var valid_test_tags_default = createRule({
|
|
3844
|
+
create(context) {
|
|
3845
|
+
const options = context.options[0] || {};
|
|
3846
|
+
const allowedTags = options.allowedTags || [];
|
|
3847
|
+
const disallowedTags = options.disallowedTags || [];
|
|
3848
|
+
if (allowedTags.length > 0 && disallowedTags.length > 0) {
|
|
3849
|
+
throw new Error(
|
|
3850
|
+
"The allowedTags and disallowedTags options cannot be used together"
|
|
3851
|
+
);
|
|
3852
|
+
}
|
|
3853
|
+
for (const tag of [...allowedTags, ...disallowedTags]) {
|
|
3854
|
+
if (typeof tag === "string" && !tag.startsWith("@")) {
|
|
3855
|
+
throw new Error(
|
|
3856
|
+
`Invalid tag "${tag}" in configuration: tags must start with @`
|
|
3857
|
+
);
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
const validateTag = (tag, node) => {
|
|
3861
|
+
if (!tag.startsWith("@")) {
|
|
3862
|
+
context.report({
|
|
3863
|
+
messageId: "invalidTagFormat",
|
|
3864
|
+
node
|
|
3865
|
+
});
|
|
3866
|
+
return;
|
|
3867
|
+
}
|
|
3868
|
+
if (allowedTags.length > 0) {
|
|
3869
|
+
const isAllowed = allowedTags.some(
|
|
3870
|
+
(pattern) => pattern instanceof RegExp ? pattern.test(tag) : pattern === tag
|
|
3871
|
+
);
|
|
3872
|
+
if (!isAllowed) {
|
|
3873
|
+
context.report({
|
|
3874
|
+
data: { tag },
|
|
3875
|
+
messageId: "unknownTag",
|
|
3876
|
+
node
|
|
3877
|
+
});
|
|
3878
|
+
return;
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
if (disallowedTags.length > 0) {
|
|
3882
|
+
const isDisallowed = disallowedTags.some(
|
|
3883
|
+
(pattern) => pattern instanceof RegExp ? pattern.test(tag) : pattern === tag
|
|
3884
|
+
);
|
|
3885
|
+
if (isDisallowed) {
|
|
3886
|
+
context.report({
|
|
3887
|
+
data: { tag },
|
|
3888
|
+
messageId: "disallowedTag",
|
|
3889
|
+
node
|
|
3890
|
+
});
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
};
|
|
3894
|
+
return {
|
|
3895
|
+
CallExpression(node) {
|
|
3896
|
+
const call = parseFnCall(context, node);
|
|
3897
|
+
if (!call)
|
|
3898
|
+
return;
|
|
3899
|
+
const { type } = call;
|
|
3900
|
+
if (type !== "test" && type !== "describe" && type !== "step")
|
|
3901
|
+
return;
|
|
3902
|
+
if (node.arguments.length < 2)
|
|
3903
|
+
return;
|
|
3904
|
+
const optionsArg = node.arguments[1];
|
|
3905
|
+
if (!optionsArg || optionsArg.type !== "ObjectExpression")
|
|
3906
|
+
return;
|
|
3907
|
+
const tagProperty = optionsArg.properties.find(
|
|
3908
|
+
(prop) => prop.type === "Property" && !("argument" in prop) && // Ensure it's not a spread element
|
|
3909
|
+
prop.key.type === "Identifier" && prop.key.name === "tag"
|
|
3910
|
+
);
|
|
3911
|
+
if (!tagProperty)
|
|
3912
|
+
return;
|
|
3913
|
+
const tagValue = tagProperty.value;
|
|
3914
|
+
if (tagValue.type === "Literal") {
|
|
3915
|
+
if (typeof tagValue.value !== "string") {
|
|
3916
|
+
context.report({
|
|
3917
|
+
messageId: "invalidTagValue",
|
|
3918
|
+
node
|
|
3919
|
+
});
|
|
3920
|
+
return;
|
|
3921
|
+
}
|
|
3922
|
+
validateTag(tagValue.value, node);
|
|
3923
|
+
} else if (tagValue.type === "ArrayExpression") {
|
|
3924
|
+
for (const element of tagValue.elements) {
|
|
3925
|
+
if (!element || element.type !== "Literal" || typeof element.value !== "string") {
|
|
3926
|
+
return;
|
|
3927
|
+
}
|
|
3928
|
+
validateTag(element.value, node);
|
|
3929
|
+
}
|
|
3930
|
+
} else {
|
|
3931
|
+
context.report({
|
|
3932
|
+
messageId: "invalidTagValue",
|
|
3933
|
+
node
|
|
3934
|
+
});
|
|
3935
|
+
}
|
|
3936
|
+
}
|
|
3937
|
+
};
|
|
3938
|
+
},
|
|
3939
|
+
meta: {
|
|
3940
|
+
docs: {
|
|
3941
|
+
description: "Enforce valid tag format in Playwright test blocks",
|
|
3942
|
+
recommended: true
|
|
3943
|
+
},
|
|
3944
|
+
messages: {
|
|
3945
|
+
disallowedTag: 'Tag "{{tag}}" is not allowed',
|
|
3946
|
+
invalidTagFormat: "Tag must start with @",
|
|
3947
|
+
invalidTagValue: "Tag must be a string or array of strings",
|
|
3948
|
+
unknownTag: 'Unknown tag "{{tag}}"'
|
|
3949
|
+
},
|
|
3950
|
+
schema: [
|
|
3951
|
+
{
|
|
3952
|
+
additionalProperties: false,
|
|
3953
|
+
properties: {
|
|
3954
|
+
allowedTags: {
|
|
3955
|
+
items: {
|
|
3956
|
+
oneOf: [
|
|
3957
|
+
{ type: "string" },
|
|
3958
|
+
{ properties: { source: { type: "string" } }, type: "object" }
|
|
3959
|
+
]
|
|
3960
|
+
},
|
|
3961
|
+
type: "array"
|
|
3962
|
+
},
|
|
3963
|
+
disallowedTags: {
|
|
3964
|
+
items: {
|
|
3965
|
+
oneOf: [
|
|
3966
|
+
{ type: "string" },
|
|
3967
|
+
{ properties: { source: { type: "string" } }, type: "object" }
|
|
3968
|
+
]
|
|
3969
|
+
},
|
|
3970
|
+
type: "array"
|
|
3971
|
+
}
|
|
3972
|
+
},
|
|
3973
|
+
type: "object"
|
|
3974
|
+
}
|
|
3975
|
+
],
|
|
3976
|
+
type: "problem"
|
|
3977
|
+
}
|
|
3978
|
+
});
|
|
3979
|
+
|
|
3792
3980
|
// src/rules/valid-title.ts
|
|
3793
3981
|
var doesBinaryExpressionContainStringNode = (binaryExp) => {
|
|
3794
3982
|
if (isStringNode(binaryExp.right)) {
|
|
@@ -4037,6 +4225,7 @@ var index = {
|
|
|
4037
4225
|
"no-unsafe-references": no_unsafe_references_default,
|
|
4038
4226
|
"no-useless-await": no_useless_await_default,
|
|
4039
4227
|
"no-useless-not": no_useless_not_default,
|
|
4228
|
+
"no-wait-for-navigation": no_wait_for_navigation_default,
|
|
4040
4229
|
"no-wait-for-selector": no_wait_for_selector_default,
|
|
4041
4230
|
"no-wait-for-timeout": no_wait_for_timeout_default,
|
|
4042
4231
|
"prefer-comparison-matcher": prefer_comparison_matcher_default,
|
|
@@ -4059,6 +4248,7 @@ var index = {
|
|
|
4059
4248
|
"valid-describe-callback": valid_describe_callback_default,
|
|
4060
4249
|
"valid-expect": valid_expect_default,
|
|
4061
4250
|
"valid-expect-in-promise": valid_expect_in_promise_default,
|
|
4251
|
+
"valid-test-tags": valid_test_tags_default,
|
|
4062
4252
|
"valid-title": valid_title_default
|
|
4063
4253
|
}
|
|
4064
4254
|
};
|
|
@@ -4082,6 +4272,7 @@ var sharedConfig = {
|
|
|
4082
4272
|
"playwright/no-unsafe-references": "error",
|
|
4083
4273
|
"playwright/no-useless-await": "warn",
|
|
4084
4274
|
"playwright/no-useless-not": "warn",
|
|
4275
|
+
"playwright/no-wait-for-navigation": "error",
|
|
4085
4276
|
"playwright/no-wait-for-selector": "warn",
|
|
4086
4277
|
"playwright/no-wait-for-timeout": "warn",
|
|
4087
4278
|
"playwright/prefer-web-first-assertions": "error",
|
package/package.json
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-playwright",
|
|
3
3
|
"description": "ESLint plugin for Playwright testing.",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"repository": "https://github.com/playwright-community/eslint-plugin-playwright",
|
|
6
6
|
"author": "Mark Skelton <mark@mskelton.dev>",
|
|
7
|
-
"packageManager": "pnpm@8.12.0",
|
|
8
7
|
"contributors": [
|
|
9
8
|
"Max Schmitt <max@schmitt.mx>"
|
|
10
9
|
],
|
|
11
10
|
"license": "MIT",
|
|
12
|
-
"workspaces": [
|
|
13
|
-
"examples"
|
|
14
|
-
],
|
|
15
11
|
"engines": {
|
|
16
12
|
"node": ">=16.6.0"
|
|
17
13
|
},
|
|
@@ -30,34 +26,10 @@
|
|
|
30
26
|
"index.cjs",
|
|
31
27
|
"index.d.ts"
|
|
32
28
|
],
|
|
33
|
-
"scripts": {
|
|
34
|
-
"build": "tsup src/index.ts --format cjs --out-dir dist",
|
|
35
|
-
"lint": "eslint .",
|
|
36
|
-
"fmt": "prettier --write .",
|
|
37
|
-
"fmt:check": "prettier --check .",
|
|
38
|
-
"test": "vitest",
|
|
39
|
-
"test:watch": "vitest --reporter=dot",
|
|
40
|
-
"ts": "tsc --noEmit"
|
|
41
|
-
},
|
|
42
29
|
"peerDependencies": {
|
|
43
30
|
"eslint": ">=8.40.0"
|
|
44
31
|
},
|
|
45
32
|
"dependencies": {
|
|
46
33
|
"globals": "^13.23.0"
|
|
47
|
-
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@mskelton/eslint-config": "^9.0.1",
|
|
50
|
-
"@mskelton/semantic-release-config": "^1.0.1",
|
|
51
|
-
"@types/estree": "^1.0.6",
|
|
52
|
-
"@types/node": "^20.11.17",
|
|
53
|
-
"@typescript-eslint/parser": "^8.11.0",
|
|
54
|
-
"dedent": "^1.5.1",
|
|
55
|
-
"eslint": "^9.13.0",
|
|
56
|
-
"prettier": "^3.0.3",
|
|
57
|
-
"prettier-plugin-jsdoc": "^1.3.0",
|
|
58
|
-
"semantic-release": "^23.0.2",
|
|
59
|
-
"tsup": "^8.0.1",
|
|
60
|
-
"typescript": "^5.2.2",
|
|
61
|
-
"vitest": "^1.3.1"
|
|
62
34
|
}
|
|
63
35
|
}
|