eslint-plugin-playwright 2.10.0 → 2.10.2

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.
Files changed (2) hide show
  1. package/dist/index.cjs +70 -33
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -324,8 +324,14 @@ function parse(context, node) {
324
324
  return null;
325
325
  }
326
326
  let type = group;
327
- if ((name === "test" || name === "describe") && (node.arguments.length < 2 || !isFunction(node.arguments.at(-1)))) {
328
- type = "config";
327
+ if (name === "describe") {
328
+ if (!isFunction(node.arguments.at(-1))) {
329
+ type = "config";
330
+ }
331
+ } else if (name === "test") {
332
+ if (node.arguments.length < 2 || !isFunction(node.arguments.at(-1))) {
333
+ type = "config";
334
+ }
329
335
  }
330
336
  return {
331
337
  ...parsedFnCall,
@@ -392,8 +398,21 @@ function findParent(node, type) {
392
398
  function dig(node, identifier) {
393
399
  return node.type === "MemberExpression" ? dig(node.property, identifier) : node.type === "CallExpression" ? dig(node.callee, identifier) : node.type === "Identifier" ? isIdentifier(node, identifier) : false;
394
400
  }
401
+ var pageFrameFullPattern = /(^(page|frame)|(Page|Frame)$)/;
402
+ var pageFramePrefixPattern = /^(page|frame)/;
395
403
  function isPageMethod(node, name) {
396
- return node.callee.type === "MemberExpression" && dig(node.callee.object, /(^(page|frame)|(Page|Frame)$)/) && isPropertyAccessor(node.callee, name);
404
+ if (node.callee.type !== "MemberExpression") {
405
+ return false;
406
+ }
407
+ if (!isPropertyAccessor(node.callee, name)) {
408
+ return false;
409
+ }
410
+ const obj = node.callee.object;
411
+ if (obj.type === "MemberExpression") {
412
+ const pattern = obj.object.type === "ThisExpression" ? pageFrameFullPattern : pageFramePrefixPattern;
413
+ return isIdentifier(obj.property, pattern);
414
+ }
415
+ return dig(obj, pageFrameFullPattern);
397
416
  }
398
417
  function isFunction(node) {
399
418
  return node?.type === "ArrowFunctionExpression" || node?.type === "FunctionExpression";
@@ -849,6 +868,9 @@ var max_nested_describe_default = createRule({
849
868
 
850
869
  // src/rules/missing-playwright-await.ts
851
870
  var validTypes = /* @__PURE__ */ new Set(["AwaitExpression", "ReturnStatement", "ArrowFunctionExpression"]);
871
+ function isArrayLike(node) {
872
+ return node.type === "ArrayExpression" || node.type === "NewExpression" && isIdentifier(node.callee, "Array") || node.type === "CallExpression" && node.callee.type === "MemberExpression" && isIdentifier(node.callee.object, "Array");
873
+ }
852
874
  var waitForMethods = [
853
875
  "waitForConsoleMessage",
854
876
  "waitForDownload",
@@ -1042,29 +1064,26 @@ var missing_playwright_await_default = createRule({
1042
1064
  // Add any custom matchers to the set
1043
1065
  ...options.customMatchers || []
1044
1066
  ]);
1045
- function isVariableConsumed(declarator, checkValidity2, validTypes2, visited) {
1046
- const variables = context.sourceCode.getDeclaredVariables(declarator);
1047
- for (const variable of variables) {
1048
- for (const ref of variable.references) {
1049
- if (!ref.isRead()) {
1050
- continue;
1051
- }
1052
- const refParent = ref.identifier.parent;
1053
- if (visited.has(refParent)) {
1054
- continue;
1055
- }
1056
- if (validTypes2.has(refParent.type)) {
1057
- return true;
1058
- }
1059
- if (refParent.type === "VariableDeclarator") {
1060
- if (checkValidity2(ref.identifier, visited)) {
1061
- return true;
1062
- }
1063
- continue;
1064
- }
1065
- if (checkValidity2(refParent, visited)) {
1067
+ function isVariableConsumed(variable, visited) {
1068
+ for (const ref of variable.references) {
1069
+ if (!ref.isRead()) {
1070
+ continue;
1071
+ }
1072
+ const refParent = ref.identifier.parent;
1073
+ if (!refParent || visited.has(refParent)) {
1074
+ continue;
1075
+ }
1076
+ if (validTypes.has(refParent.type)) {
1077
+ return true;
1078
+ }
1079
+ if (refParent.type === "VariableDeclarator") {
1080
+ if (checkValidity(ref.identifier, visited)) {
1066
1081
  return true;
1067
1082
  }
1083
+ continue;
1084
+ }
1085
+ if (checkValidity(refParent, visited)) {
1086
+ return true;
1068
1087
  }
1069
1088
  }
1070
1089
  return false;
@@ -1109,7 +1128,19 @@ var missing_playwright_await_default = createRule({
1109
1128
  return checkValidity(parent, visited);
1110
1129
  }
1111
1130
  if (parent.type === "VariableDeclarator") {
1112
- return isVariableConsumed(parent, checkValidity, validTypes, visited);
1131
+ return context.sourceCode.getDeclaredVariables(parent).some((v) => isVariableConsumed(v, visited));
1132
+ }
1133
+ if (parent.type === "AssignmentExpression" && parent.right === node && parent.left.type === "Identifier") {
1134
+ const parentName = parent.left.name;
1135
+ let scope = context.sourceCode.getScope(node);
1136
+ while (scope) {
1137
+ const variable = scope.variables.find((v) => v.name === parentName);
1138
+ if (variable) {
1139
+ return isVariableConsumed(variable, visited);
1140
+ }
1141
+ scope = scope.upper;
1142
+ }
1143
+ return false;
1113
1144
  }
1114
1145
  return false;
1115
1146
  }
@@ -1128,7 +1159,7 @@ var missing_playwright_await_default = createRule({
1128
1159
  }
1129
1160
  if (includePageLocatorMethods && node.callee.type === "MemberExpression") {
1130
1161
  const methodName = getStringValue(node.callee.property);
1131
- const isPlaywrightMethod = locatorMethods.has(methodName) || pageMethods.has(methodName) && isPageMethod(node, methodName);
1162
+ const isPlaywrightMethod = !isArrayLike(node.callee.object) && (locatorMethods.has(methodName) || pageMethods.has(methodName) && isPageMethod(node, methodName));
1132
1163
  if (isPlaywrightMethod) {
1133
1164
  if (!checkValidity(node, /* @__PURE__ */ new Set())) {
1134
1165
  context.report({
@@ -4545,8 +4576,8 @@ var valid_test_tags_default = createRule({
4545
4576
  }
4546
4577
  if (node.arguments.length > 0) {
4547
4578
  const titleArg = node.arguments[0];
4548
- if (titleArg && titleArg.type === "Literal" && typeof titleArg.value === "string") {
4549
- const titleTags = extractTagsFromTitle(titleArg.value);
4579
+ if (titleArg) {
4580
+ const titleTags = extractTagsFromTitle(getStringValue(titleArg));
4550
4581
  for (const tag of titleTags) {
4551
4582
  validateTag(tag, node);
4552
4583
  }
@@ -4567,21 +4598,27 @@ var valid_test_tags_default = createRule({
4567
4598
  return;
4568
4599
  }
4569
4600
  const tagValue = tagProperty.value;
4570
- if (tagValue.type === "Literal") {
4571
- if (typeof tagValue.value !== "string") {
4601
+ if (tagValue.type === "Literal" || tagValue.type === "TemplateLiteral") {
4602
+ if (tagValue.type === "Literal" && typeof tagValue.value !== "string") {
4572
4603
  context.report({
4573
4604
  messageId: "invalidTagValue",
4574
4605
  node
4575
4606
  });
4576
4607
  return;
4577
4608
  }
4578
- validateTag(tagValue.value, node);
4609
+ validateTag(getStringValue(tagValue), node);
4579
4610
  } else if (tagValue.type === "ArrayExpression") {
4580
4611
  for (const element of tagValue.elements) {
4581
- if (!element || element.type !== "Literal" || typeof element.value !== "string") {
4612
+ if (!element) {
4613
+ return;
4614
+ }
4615
+ if (element.type !== "Literal" && element.type !== "TemplateLiteral") {
4616
+ return;
4617
+ }
4618
+ if (element.type === "Literal" && typeof element.value !== "string") {
4582
4619
  return;
4583
4620
  }
4584
- validateTag(element.value, node);
4621
+ validateTag(getStringValue(element), node);
4585
4622
  }
4586
4623
  } else {
4587
4624
  context.report({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-playwright",
3
- "version": "2.10.0",
3
+ "version": "2.10.2",
4
4
  "description": "ESLint plugin for Playwright testing.",
5
5
  "license": "MIT",
6
6
  "author": "Mark Skelton <mark@mskelton.dev>",