playwright-cucumber-ts-steps 1.1.0 → 1.1.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.
@@ -8,10 +8,6 @@ interface RunnerOptions {
8
8
  tags?: string;
9
9
  dbQuery?: (query: string) => Promise<any>;
10
10
  }
11
- /**
12
- * The main test runner. Parses feature files and executes them as Playwright tests.
13
- * Includes support for Data Tables and Auto-Screenshots.
14
- */
15
11
  export declare function runTests(featureGlob: string, options?: RunnerOptions): void;
16
12
  export {};
17
13
  //# sourceMappingURL=runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAOA,OAAO,0BAA0B,CAAC;AAClC,OAAO,6BAA6B,CAAC;AACrC,OAAO,2BAA2B,CAAC;AACnC,OAAO,sBAAsB,CAAC;AAC9B,OAAO,uBAAuB,CAAC;AAE/B,OAAO,qBAAqB,CAAC;AAE7B,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,QAgIpE"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAMA,OAAO,0BAA0B,CAAC;AAClC,OAAO,6BAA6B,CAAC;AACrC,OAAO,2BAA2B,CAAC;AACnC,OAAO,sBAAsB,CAAC;AAC9B,OAAO,uBAAuB,CAAC;AAE/B,OAAO,qBAAqB,CAAC;AAE7B,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CAC3C;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,QAmGpE"}
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.runTests = runTests;
37
- // src/core/runner.ts
38
37
  const test_1 = require("@playwright/test");
39
38
  const fs = __importStar(require("fs"));
40
39
  const glob_1 = require("glob");
@@ -46,21 +45,14 @@ require("../backend/elements/index");
46
45
  require("../backend/api/index");
47
46
  require("../backend/auth/index");
48
47
  const state_1 = require("../backend/db/state");
49
- require("../backend/db/index"); // Register DB steps
50
- /**
51
- * The main test runner. Parses feature files and executes them as Playwright tests.
52
- * Includes support for Data Tables and Auto-Screenshots.
53
- */
48
+ require("../backend/db/index");
54
49
  function runTests(featureGlob, options) {
55
- // 1. Register DB Adapter if provided
56
50
  if (options?.dbQuery) {
57
51
  state_1.dbState.setAdapter(options.dbQuery);
58
52
  }
59
- // Debugging: Verify files are found to help user troubleshoot paths
60
53
  const files = (0, glob_1.globSync)(featureGlob);
61
54
  if (files.length === 0) {
62
- console.warn(`⚠️ No Feature files found matching: "${featureGlob}"`);
63
- console.warn(` Current Directory: ${process.cwd()}`);
55
+ console.warn(`⚠️ No feature files found for pattern: ${featureGlob}`);
64
56
  }
65
57
  for (const file of files) {
66
58
  const content = fs.readFileSync(file, "utf8");
@@ -69,15 +61,10 @@ function runTests(featureGlob, options) {
69
61
  ? featureMatch[1].trim()
70
62
  : "Unnamed Feature";
71
63
  test_1.test.describe(featureName, () => {
72
- // 2. SAFER REGEX FIX
73
- // Old: /(@[\w\s@]+)\s+)?Scenario:... (Too greedy, ate newlines)
74
- // New: /(@[^:\r\n]+)\s+)?Scenario:... (Stops strictly at newlines/colons)
64
+ // 1. SAFE SCENARIO REGEX
75
65
  const scenarioRegex = /(?:(@[^:\r\n]+)\s+)?Scenario:\s*(.+)/g;
76
66
  let match;
77
- let scenarioCount = 0;
78
67
  while ((match = scenarioRegex.exec(content)) !== null) {
79
- scenarioCount++;
80
- // 1. CAPTURE DATA IMMEDIATELY
81
68
  const foundTags = match[1] || "";
82
69
  const scenarioName = match[2].trim();
83
70
  const startIndex = match.index + match[0].length;
@@ -93,47 +80,40 @@ function runTests(featureGlob, options) {
93
80
  .split("\n")
94
81
  .map((l) => l.trim())
95
82
  .filter((l) => l);
96
- // CHANGED: Use index loop to handle Data Tables (look-ahead)
97
83
  for (let i = 0; i < lines.length; i++) {
98
84
  const stepText = lines[i];
99
85
  if (stepText.startsWith("#") ||
100
86
  stepText.startsWith("@") ||
101
87
  stepText === "")
102
88
  continue;
103
- // 2. CHECK FOR DATA TABLE
104
- // We look at the NEXT lines to see if they start with a pipe '|'
89
+ // Handle Data Tables
105
90
  const tableData = [];
106
91
  while (i + 1 < lines.length && lines[i + 1].startsWith("|")) {
107
- i++; // Move the index forward so we don't process this line as a step
92
+ i++;
108
93
  const row = lines[i]
109
94
  .split("|")
110
95
  .map((cell) => cell.trim())
111
- .filter((cell) => cell !== ""); // Remove empty start/end strings from split
96
+ .filter((cell) => cell !== "");
112
97
  tableData.push(row);
113
98
  }
114
- // 3. CLEAN STEP TEXT
115
- // Remove "Given/When/..." and trailing colons ":"
116
99
  const cleanStep = stepText
117
100
  .replace(/^(Given|When|Then|And|But)\s+/i, "")
118
101
  .replace(/:$/, "")
119
102
  .trim();
120
- const stepDef = findMatchingStep(cleanStep);
121
- if (!stepDef) {
103
+ // 2. SMART STEP MATCHING
104
+ const matchResult = findMatchingStep(cleanStep);
105
+ if (!matchResult) {
122
106
  throw new Error(`❌ Undefined Step: "${cleanStep}"`);
123
107
  }
124
- // 4. EXECUTE WITH ERROR HANDLING
125
108
  try {
126
- // Construct arguments: Regex args + Table data (if exists)
127
- const args = [...stepDef.args];
128
- if (tableData.length > 0) {
109
+ const args = [...matchResult.args];
110
+ if (tableData.length > 0)
129
111
  args.push(tableData);
130
- }
131
- // Pass 'page' + args to the step function
132
- await stepDef.fn(page, ...args);
112
+ console.log(`✅ Executing: ${cleanStep}`);
113
+ await matchResult.fn(page, ...args);
133
114
  }
134
115
  catch (error) {
135
116
  console.error(`❌ Failed at step: "${stepText}"`);
136
- // Take a screenshot immediately
137
117
  const screenshot = await page.screenshot({
138
118
  fullPage: true,
139
119
  type: "png",
@@ -147,18 +127,35 @@ function runTests(featureGlob, options) {
147
127
  }
148
128
  });
149
129
  }
150
- // Safety check log: warn if we opened a file but found no scenarios
151
- if (scenarioCount === 0) {
152
- console.warn(`⚠️ Found "Feature:" in ${file} but 0 Scenarios. Check regex or formatting.`);
153
- }
154
130
  });
155
131
  }
156
132
  }
133
+ // 3. ROBUST FINDER FUNCTION
157
134
  function findMatchingStep(text) {
158
135
  for (const step of registry_1.stepRegistry) {
159
- const match = step.expression.match(text);
160
- if (match) {
161
- return { fn: step.fn, args: match.map((arg) => arg.getValue(null)) };
136
+ // A. Handle RegExp (If you defined steps with Regex)
137
+ if (step.expression instanceof RegExp) {
138
+ const match = step.expression.exec(text);
139
+ if (match) {
140
+ return { fn: step.fn, args: match.slice(1) };
141
+ }
142
+ }
143
+ // B. Handle Cucumber Expressions (The Objects we saw in your logs)
144
+ // We check if it has a .match() method
145
+ else if (typeof step.expression.match === "function") {
146
+ const match = step.expression.match(text);
147
+ if (match) {
148
+ return {
149
+ fn: step.fn,
150
+ args: match.map((arg) => arg.getValue(null)),
151
+ };
152
+ }
153
+ }
154
+ // C. Handle Simple Strings
155
+ else if (typeof step.expression === "string") {
156
+ if (step.expression === text) {
157
+ return { fn: step.fn, args: [] };
158
+ }
162
159
  }
163
160
  }
164
161
  return null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "playwright-cucumber-ts-steps",
3
3
  "description": "A collection of reusable Playwright step definitions for Cucumber in TypeScript, designed to streamline end-to-end testing across web, API, and mobile applications.",
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",