eslint-plugin-playwright 0.20.0 → 0.22.0

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 CHANGED
@@ -162,6 +162,7 @@ command line option.\
162
162
  | | | | [no-restricted-matchers](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-restricted-matchers.md) | Disallow specific matchers & modifiers |
163
163
  | ✔ | | 💡 | [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 |
164
164
  | ✔ | 🔧 | | [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 |
165
+ | ✔ | | 💡 | [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` |
165
166
  | ✔ | | 💡 | [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` |
166
167
  | | | 💡 | [prefer-strict-equal](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-strict-equal.md) | Suggest using `toStrictEqual()` |
167
168
  | | 🔧 | | [prefer-lowercase-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-lowercase-title.md) | Enforce lowercase test names |
package/dist/index.d.mts CHANGED
@@ -27,6 +27,7 @@ declare const _default: {
27
27
  'no-skipped-test': eslint.Rule.RuleModule;
28
28
  'no-useless-await': eslint.Rule.RuleModule;
29
29
  'no-useless-not': eslint.Rule.RuleModule;
30
+ 'no-wait-for-selector': eslint.Rule.RuleModule;
30
31
  'no-wait-for-timeout': eslint.Rule.RuleModule;
31
32
  'prefer-lowercase-title': eslint.Rule.RuleModule;
32
33
  'prefer-strict-equal': eslint.Rule.RuleModule;
@@ -75,6 +76,7 @@ declare const _default: {
75
76
  'no-skipped-test': eslint.Rule.RuleModule;
76
77
  'no-useless-await': eslint.Rule.RuleModule;
77
78
  'no-useless-not': eslint.Rule.RuleModule;
79
+ 'no-wait-for-selector': eslint.Rule.RuleModule;
78
80
  'no-wait-for-timeout': eslint.Rule.RuleModule;
79
81
  'prefer-lowercase-title': eslint.Rule.RuleModule;
80
82
  'prefer-strict-equal': eslint.Rule.RuleModule;
@@ -106,6 +108,7 @@ declare const _default: {
106
108
  'playwright/no-skipped-test': string;
107
109
  'playwright/no-useless-await': string;
108
110
  'playwright/no-useless-not': string;
111
+ 'playwright/no-wait-for-selector': string;
109
112
  'playwright/no-wait-for-timeout': string;
110
113
  'playwright/prefer-web-first-assertions': string;
111
114
  'playwright/valid-expect': string;
@@ -155,6 +158,7 @@ declare const _default: {
155
158
  'playwright/no-skipped-test': string;
156
159
  'playwright/no-useless-await': string;
157
160
  'playwright/no-useless-not': string;
161
+ 'playwright/no-wait-for-selector': string;
158
162
  'playwright/no-wait-for-timeout': string;
159
163
  'playwright/prefer-web-first-assertions': string;
160
164
  'playwright/valid-expect': string;
@@ -182,6 +186,7 @@ declare const _default: {
182
186
  'playwright/no-skipped-test': string;
183
187
  'playwright/no-useless-await': string;
184
188
  'playwright/no-useless-not': string;
189
+ 'playwright/no-wait-for-selector': string;
185
190
  'playwright/no-wait-for-timeout': string;
186
191
  'playwright/prefer-web-first-assertions': string;
187
192
  'playwright/valid-expect': string;
@@ -207,6 +212,7 @@ declare const _default: {
207
212
  'no-skipped-test': eslint.Rule.RuleModule;
208
213
  'no-useless-await': eslint.Rule.RuleModule;
209
214
  'no-useless-not': eslint.Rule.RuleModule;
215
+ 'no-wait-for-selector': eslint.Rule.RuleModule;
210
216
  'no-wait-for-timeout': eslint.Rule.RuleModule;
211
217
  'prefer-lowercase-title': eslint.Rule.RuleModule;
212
218
  'prefer-strict-equal': eslint.Rule.RuleModule;
package/dist/index.d.ts CHANGED
@@ -27,6 +27,7 @@ declare const _default: {
27
27
  'no-skipped-test': eslint.Rule.RuleModule;
28
28
  'no-useless-await': eslint.Rule.RuleModule;
29
29
  'no-useless-not': eslint.Rule.RuleModule;
30
+ 'no-wait-for-selector': eslint.Rule.RuleModule;
30
31
  'no-wait-for-timeout': eslint.Rule.RuleModule;
31
32
  'prefer-lowercase-title': eslint.Rule.RuleModule;
32
33
  'prefer-strict-equal': eslint.Rule.RuleModule;
@@ -75,6 +76,7 @@ declare const _default: {
75
76
  'no-skipped-test': eslint.Rule.RuleModule;
76
77
  'no-useless-await': eslint.Rule.RuleModule;
77
78
  'no-useless-not': eslint.Rule.RuleModule;
79
+ 'no-wait-for-selector': eslint.Rule.RuleModule;
78
80
  'no-wait-for-timeout': eslint.Rule.RuleModule;
79
81
  'prefer-lowercase-title': eslint.Rule.RuleModule;
80
82
  'prefer-strict-equal': eslint.Rule.RuleModule;
@@ -106,6 +108,7 @@ declare const _default: {
106
108
  'playwright/no-skipped-test': string;
107
109
  'playwright/no-useless-await': string;
108
110
  'playwright/no-useless-not': string;
111
+ 'playwright/no-wait-for-selector': string;
109
112
  'playwright/no-wait-for-timeout': string;
110
113
  'playwright/prefer-web-first-assertions': string;
111
114
  'playwright/valid-expect': string;
@@ -155,6 +158,7 @@ declare const _default: {
155
158
  'playwright/no-skipped-test': string;
156
159
  'playwright/no-useless-await': string;
157
160
  'playwright/no-useless-not': string;
161
+ 'playwright/no-wait-for-selector': string;
158
162
  'playwright/no-wait-for-timeout': string;
159
163
  'playwright/prefer-web-first-assertions': string;
160
164
  'playwright/valid-expect': string;
@@ -182,6 +186,7 @@ declare const _default: {
182
186
  'playwright/no-skipped-test': string;
183
187
  'playwright/no-useless-await': string;
184
188
  'playwright/no-useless-not': string;
189
+ 'playwright/no-wait-for-selector': string;
185
190
  'playwright/no-wait-for-timeout': string;
186
191
  'playwright/prefer-web-first-assertions': string;
187
192
  'playwright/valid-expect': string;
@@ -207,6 +212,7 @@ declare const _default: {
207
212
  'no-skipped-test': eslint.Rule.RuleModule;
208
213
  'no-useless-await': eslint.Rule.RuleModule;
209
214
  'no-useless-not': eslint.Rule.RuleModule;
215
+ 'no-wait-for-selector': eslint.Rule.RuleModule;
210
216
  'no-wait-for-timeout': eslint.Rule.RuleModule;
211
217
  'prefer-lowercase-title': eslint.Rule.RuleModule;
212
218
  'prefer-strict-equal': eslint.Rule.RuleModule;
package/dist/index.js CHANGED
@@ -303,31 +303,27 @@ var playwrightTestMatchers = [
303
303
  ];
304
304
  function getCallType(node, awaitableMatchers) {
305
305
  if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object, "test") && isPropertyAccessor(node.callee, "step")) {
306
- return { messageId: "testStep" };
306
+ return { messageId: "testStep", node };
307
307
  }
308
308
  const expectType = getExpectType(node);
309
309
  if (!expectType)
310
310
  return;
311
- if (expectType === "poll") {
312
- return { messageId: "expectPoll" };
313
- }
314
311
  const [lastMatcher] = getMatchers(node).slice(-1);
312
+ const grandparent = lastMatcher?.parent?.parent;
313
+ if (grandparent?.type !== "CallExpression")
314
+ return;
315
315
  const matcherName = getStringValue(lastMatcher);
316
- if (awaitableMatchers.has(matcherName)) {
317
- return { data: { matcherName }, messageId: "expect" };
316
+ if (expectType === "poll" || awaitableMatchers.has(matcherName)) {
317
+ return {
318
+ data: { matcherName },
319
+ messageId: expectType === "poll" ? "expectPoll" : "expect",
320
+ node: grandparent
321
+ };
318
322
  }
319
323
  }
320
- function isPromiseAll(node) {
321
- return node.type === "ArrayExpression" && node.parent.type === "CallExpression" && node.parent.callee.type === "MemberExpression" && isIdentifier(node.parent.callee.object, "Promise") && isIdentifier(node.parent.callee.property, "all") ? node.parent : null;
322
- }
323
- function checkValidity(node) {
324
- if (validTypes.has(node.parent.type))
325
- return;
326
- const promiseAll = isPromiseAll(node.parent);
327
- return promiseAll ? checkValidity(promiseAll) : node.parent.type === "MemberExpression" || node.parent.type === "CallExpression" && node.parent.callee === node ? checkValidity(node.parent) : node;
328
- }
329
324
  var missing_playwright_await_default = {
330
325
  create(context) {
326
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
331
327
  const options = context.options[0] || {};
332
328
  const awaitableMatchers = /* @__PURE__ */ new Set([
333
329
  ...expectPlaywrightMatchers,
@@ -335,11 +331,33 @@ var missing_playwright_await_default = {
335
331
  // Add any custom matchers to the set
336
332
  ...options.customMatchers || []
337
333
  ]);
334
+ function checkValidity(node) {
335
+ if (validTypes.has(node.parent.type))
336
+ return true;
337
+ if (node.parent.type === "ArrayExpression") {
338
+ return checkValidity(node.parent);
339
+ }
340
+ if (node.parent.type === "CallExpression" && node.parent.callee.type === "MemberExpression" && isIdentifier(node.parent.callee.object, "Promise") && isIdentifier(node.parent.callee.property, "all")) {
341
+ return true;
342
+ }
343
+ if (node.parent.type === "VariableDeclarator") {
344
+ const scope = sourceCode.getScope(node.parent.parent);
345
+ for (const ref of scope.references) {
346
+ const refParent = ref.identifier.parent;
347
+ if (validTypes.has(refParent.type))
348
+ return true;
349
+ if (checkValidity(refParent))
350
+ return true;
351
+ }
352
+ }
353
+ return false;
354
+ }
338
355
  return {
339
356
  CallExpression(node) {
340
357
  const result = getCallType(node, awaitableMatchers);
341
- const reportNode = result ? checkValidity(node) : void 0;
342
- if (result && reportNode) {
358
+ console.log(result);
359
+ const isValid = result ? checkValidity(result.node) : false;
360
+ if (result && !isValid) {
343
361
  context.report({
344
362
  data: result.data,
345
363
  fix: (fixer) => fixer.insertTextBefore(node, "await "),
@@ -748,14 +766,27 @@ var no_page_pause_default = {
748
766
  };
749
767
 
750
768
  // src/rules/no-raw-locators.ts
769
+ function normalize(str) {
770
+ const match = /\[([^=]+?)=['"]?([^'"]+?)['"]?\]/.exec(str);
771
+ return match ? `[${match[1]}=${match[2]}]` : str;
772
+ }
751
773
  var no_raw_locators_default = {
752
774
  create(context) {
775
+ const options = {
776
+ allowed: [],
777
+ ...context.options?.[0] ?? {}
778
+ };
779
+ function isAllowed(arg) {
780
+ return options.allowed.some((a) => normalize(a) === normalize(arg));
781
+ }
753
782
  return {
754
783
  CallExpression(node) {
755
784
  if (node.callee.type !== "MemberExpression")
756
785
  return;
757
786
  const method = getStringValue(node.callee.property);
758
- if (isPageMethod(node, "locator") || method === "locator") {
787
+ const arg = getStringValue(node.arguments[0]);
788
+ const isLocator = isPageMethod(node, "locator") || method === "locator";
789
+ if (isLocator && !isAllowed(arg)) {
759
790
  context.report({ messageId: "noRawLocator", node });
760
791
  }
761
792
  }
@@ -771,6 +802,18 @@ var no_raw_locators_default = {
771
802
  messages: {
772
803
  noRawLocator: "Usage of raw locator detected. Use methods like .getByRole() or .getByText() instead of raw locators."
773
804
  },
805
+ schema: [
806
+ {
807
+ additionalProperties: false,
808
+ properties: {
809
+ allowed: {
810
+ items: { type: "string" },
811
+ type: "array"
812
+ }
813
+ },
814
+ type: "object"
815
+ }
816
+ ],
774
817
  type: "suggestion"
775
818
  }
776
819
  };
@@ -1073,6 +1116,44 @@ var no_useless_not_default = {
1073
1116
  }
1074
1117
  };
1075
1118
 
1119
+ // src/rules/no-wait-for-selector.ts
1120
+ var no_wait_for_selector_default = {
1121
+ create(context) {
1122
+ return {
1123
+ CallExpression(node) {
1124
+ if (isPageMethod(node, "waitForSelector")) {
1125
+ context.report({
1126
+ messageId: "noWaitForSelector",
1127
+ node,
1128
+ suggest: [
1129
+ {
1130
+ fix: (fixer) => fixer.remove(
1131
+ node.parent && node.parent.type !== "AwaitExpression" ? node.parent : node.parent.parent
1132
+ ),
1133
+ messageId: "removeWaitForSelector"
1134
+ }
1135
+ ]
1136
+ });
1137
+ }
1138
+ }
1139
+ };
1140
+ },
1141
+ meta: {
1142
+ docs: {
1143
+ category: "Best Practices",
1144
+ description: "Prevent usage of page.waitForSelector()",
1145
+ recommended: true,
1146
+ url: "https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-selector.md"
1147
+ },
1148
+ hasSuggestions: true,
1149
+ messages: {
1150
+ noWaitForSelector: "Unexpected use of page.waitForSelector().",
1151
+ removeWaitForSelector: "Remove the page.waitForSelector() method."
1152
+ },
1153
+ type: "suggestion"
1154
+ }
1155
+ };
1156
+
1076
1157
  // src/rules/no-wait-for-timeout.ts
1077
1158
  var no_wait_for_timeout_default = {
1078
1159
  create(context) {
@@ -2061,6 +2142,7 @@ var index = {
2061
2142
  "no-skipped-test": no_skipped_test_default,
2062
2143
  "no-useless-await": no_useless_await_default,
2063
2144
  "no-useless-not": no_useless_not_default,
2145
+ "no-wait-for-selector": no_wait_for_selector_default,
2064
2146
  "no-wait-for-timeout": no_wait_for_timeout_default,
2065
2147
  "prefer-lowercase-title": prefer_lowercase_title_default,
2066
2148
  "prefer-strict-equal": prefer_strict_equal_default,
@@ -2092,6 +2174,7 @@ var sharedConfig = {
2092
2174
  "playwright/no-skipped-test": "warn",
2093
2175
  "playwright/no-useless-await": "warn",
2094
2176
  "playwright/no-useless-not": "warn",
2177
+ "playwright/no-wait-for-selector": "warn",
2095
2178
  "playwright/no-wait-for-timeout": "warn",
2096
2179
  "playwright/prefer-web-first-assertions": "error",
2097
2180
  "playwright/valid-expect": "error",
package/dist/index.mjs CHANGED
@@ -260,29 +260,24 @@ var init_max_nested_describe = __esm({
260
260
  // src/rules/missing-playwright-await.ts
261
261
  function getCallType(node, awaitableMatchers) {
262
262
  if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object, "test") && isPropertyAccessor(node.callee, "step")) {
263
- return { messageId: "testStep" };
263
+ return { messageId: "testStep", node };
264
264
  }
265
265
  const expectType = getExpectType(node);
266
266
  if (!expectType)
267
267
  return;
268
- if (expectType === "poll") {
269
- return { messageId: "expectPoll" };
270
- }
271
268
  const [lastMatcher] = getMatchers(node).slice(-1);
269
+ const grandparent = lastMatcher?.parent?.parent;
270
+ if (grandparent?.type !== "CallExpression")
271
+ return;
272
272
  const matcherName = getStringValue(lastMatcher);
273
- if (awaitableMatchers.has(matcherName)) {
274
- return { data: { matcherName }, messageId: "expect" };
273
+ if (expectType === "poll" || awaitableMatchers.has(matcherName)) {
274
+ return {
275
+ data: { matcherName },
276
+ messageId: expectType === "poll" ? "expectPoll" : "expect",
277
+ node: grandparent
278
+ };
275
279
  }
276
280
  }
277
- function isPromiseAll(node) {
278
- return node.type === "ArrayExpression" && node.parent.type === "CallExpression" && node.parent.callee.type === "MemberExpression" && isIdentifier(node.parent.callee.object, "Promise") && isIdentifier(node.parent.callee.property, "all") ? node.parent : null;
279
- }
280
- function checkValidity(node) {
281
- if (validTypes.has(node.parent.type))
282
- return;
283
- const promiseAll = isPromiseAll(node.parent);
284
- return promiseAll ? checkValidity(promiseAll) : node.parent.type === "MemberExpression" || node.parent.type === "CallExpression" && node.parent.callee === node ? checkValidity(node.parent) : node;
285
- }
286
281
  var validTypes, expectPlaywrightMatchers, playwrightTestMatchers, missing_playwright_await_default;
287
282
  var init_missing_playwright_await = __esm({
288
283
  "src/rules/missing-playwright-await.ts"() {
@@ -341,6 +336,7 @@ var init_missing_playwright_await = __esm({
341
336
  ];
342
337
  missing_playwright_await_default = {
343
338
  create(context) {
339
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
344
340
  const options = context.options[0] || {};
345
341
  const awaitableMatchers = /* @__PURE__ */ new Set([
346
342
  ...expectPlaywrightMatchers,
@@ -348,11 +344,33 @@ var init_missing_playwright_await = __esm({
348
344
  // Add any custom matchers to the set
349
345
  ...options.customMatchers || []
350
346
  ]);
347
+ function checkValidity(node) {
348
+ if (validTypes.has(node.parent.type))
349
+ return true;
350
+ if (node.parent.type === "ArrayExpression") {
351
+ return checkValidity(node.parent);
352
+ }
353
+ if (node.parent.type === "CallExpression" && node.parent.callee.type === "MemberExpression" && isIdentifier(node.parent.callee.object, "Promise") && isIdentifier(node.parent.callee.property, "all")) {
354
+ return true;
355
+ }
356
+ if (node.parent.type === "VariableDeclarator") {
357
+ const scope = sourceCode.getScope(node.parent.parent);
358
+ for (const ref of scope.references) {
359
+ const refParent = ref.identifier.parent;
360
+ if (validTypes.has(refParent.type))
361
+ return true;
362
+ if (checkValidity(refParent))
363
+ return true;
364
+ }
365
+ }
366
+ return false;
367
+ }
351
368
  return {
352
369
  CallExpression(node) {
353
370
  const result = getCallType(node, awaitableMatchers);
354
- const reportNode = result ? checkValidity(node) : void 0;
355
- if (result && reportNode) {
371
+ console.log(result);
372
+ const isValid = result ? checkValidity(result.node) : false;
373
+ if (result && !isValid) {
356
374
  context.report({
357
375
  data: result.data,
358
376
  fix: (fixer) => fixer.insertTextBefore(node, "await "),
@@ -826,6 +844,10 @@ var init_no_page_pause = __esm({
826
844
  });
827
845
 
828
846
  // src/rules/no-raw-locators.ts
847
+ function normalize(str) {
848
+ const match = /\[([^=]+?)=['"]?([^'"]+?)['"]?\]/.exec(str);
849
+ return match ? `[${match[1]}=${match[2]}]` : str;
850
+ }
829
851
  var no_raw_locators_default;
830
852
  var init_no_raw_locators = __esm({
831
853
  "src/rules/no-raw-locators.ts"() {
@@ -833,12 +855,21 @@ var init_no_raw_locators = __esm({
833
855
  init_ast();
834
856
  no_raw_locators_default = {
835
857
  create(context) {
858
+ const options = {
859
+ allowed: [],
860
+ ...context.options?.[0] ?? {}
861
+ };
862
+ function isAllowed(arg) {
863
+ return options.allowed.some((a) => normalize(a) === normalize(arg));
864
+ }
836
865
  return {
837
866
  CallExpression(node) {
838
867
  if (node.callee.type !== "MemberExpression")
839
868
  return;
840
869
  const method = getStringValue(node.callee.property);
841
- if (isPageMethod(node, "locator") || method === "locator") {
870
+ const arg = getStringValue(node.arguments[0]);
871
+ const isLocator = isPageMethod(node, "locator") || method === "locator";
872
+ if (isLocator && !isAllowed(arg)) {
842
873
  context.report({ messageId: "noRawLocator", node });
843
874
  }
844
875
  }
@@ -854,6 +885,18 @@ var init_no_raw_locators = __esm({
854
885
  messages: {
855
886
  noRawLocator: "Usage of raw locator detected. Use methods like .getByRole() or .getByText() instead of raw locators."
856
887
  },
888
+ schema: [
889
+ {
890
+ additionalProperties: false,
891
+ properties: {
892
+ allowed: {
893
+ items: { type: "string" },
894
+ type: "array"
895
+ }
896
+ },
897
+ type: "object"
898
+ }
899
+ ],
857
900
  type: "suggestion"
858
901
  }
859
902
  };
@@ -1202,6 +1245,51 @@ var init_no_useless_not = __esm({
1202
1245
  }
1203
1246
  });
1204
1247
 
1248
+ // src/rules/no-wait-for-selector.ts
1249
+ var no_wait_for_selector_default;
1250
+ var init_no_wait_for_selector = __esm({
1251
+ "src/rules/no-wait-for-selector.ts"() {
1252
+ "use strict";
1253
+ init_ast();
1254
+ no_wait_for_selector_default = {
1255
+ create(context) {
1256
+ return {
1257
+ CallExpression(node) {
1258
+ if (isPageMethod(node, "waitForSelector")) {
1259
+ context.report({
1260
+ messageId: "noWaitForSelector",
1261
+ node,
1262
+ suggest: [
1263
+ {
1264
+ fix: (fixer) => fixer.remove(
1265
+ node.parent && node.parent.type !== "AwaitExpression" ? node.parent : node.parent.parent
1266
+ ),
1267
+ messageId: "removeWaitForSelector"
1268
+ }
1269
+ ]
1270
+ });
1271
+ }
1272
+ }
1273
+ };
1274
+ },
1275
+ meta: {
1276
+ docs: {
1277
+ category: "Best Practices",
1278
+ description: "Prevent usage of page.waitForSelector()",
1279
+ recommended: true,
1280
+ url: "https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-selector.md"
1281
+ },
1282
+ hasSuggestions: true,
1283
+ messages: {
1284
+ noWaitForSelector: "Unexpected use of page.waitForSelector().",
1285
+ removeWaitForSelector: "Remove the page.waitForSelector() method."
1286
+ },
1287
+ type: "suggestion"
1288
+ }
1289
+ };
1290
+ }
1291
+ });
1292
+
1205
1293
  // src/rules/no-wait-for-timeout.ts
1206
1294
  var no_wait_for_timeout_default;
1207
1295
  var init_no_wait_for_timeout = __esm({
@@ -2285,6 +2373,7 @@ var require_src = __commonJS({
2285
2373
  init_no_skipped_test();
2286
2374
  init_no_useless_await();
2287
2375
  init_no_useless_not();
2376
+ init_no_wait_for_selector();
2288
2377
  init_no_wait_for_timeout();
2289
2378
  init_prefer_lowercase_title();
2290
2379
  init_prefer_strict_equal();
@@ -2317,6 +2406,7 @@ var require_src = __commonJS({
2317
2406
  "no-skipped-test": no_skipped_test_default,
2318
2407
  "no-useless-await": no_useless_await_default,
2319
2408
  "no-useless-not": no_useless_not_default,
2409
+ "no-wait-for-selector": no_wait_for_selector_default,
2320
2410
  "no-wait-for-timeout": no_wait_for_timeout_default,
2321
2411
  "prefer-lowercase-title": prefer_lowercase_title_default,
2322
2412
  "prefer-strict-equal": prefer_strict_equal_default,
@@ -2348,6 +2438,7 @@ var require_src = __commonJS({
2348
2438
  "playwright/no-skipped-test": "warn",
2349
2439
  "playwright/no-useless-await": "warn",
2350
2440
  "playwright/no-useless-not": "warn",
2441
+ "playwright/no-wait-for-selector": "warn",
2351
2442
  "playwright/no-wait-for-timeout": "warn",
2352
2443
  "playwright/prefer-web-first-assertions": "error",
2353
2444
  "playwright/valid-expect": "error",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-playwright",
3
3
  "description": "ESLint plugin for Playwright testing.",
4
- "version": "0.20.0",
4
+ "version": "0.22.0",
5
5
  "repository": "https://github.com/playwright-community/eslint-plugin-playwright",
6
6
  "author": "Mark Skelton <mark@mskelton.dev>",
7
7
  "packageManager": "pnpm@8.12.0",