playwright-cucumber-ts-steps 1.0.6 → 1.0.8

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.
@@ -1,18 +1,9 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const registry_1 = require("../../core/registry");
13
4
  const test_1 = require("@playwright/test");
14
5
  // CHANGE: Removed the ':' at the end of the string below
15
- (0, registry_1.Step)("I fill the following {string} form data", (page, formName, tableData) => __awaiter(void 0, void 0, void 0, function* () {
6
+ (0, registry_1.Step)("I fill the following {string} form data", async (page, formName, tableData) => {
16
7
  console.log(`📝 Processing Form: ${formName}`);
17
8
  // The runner passes the table data as the last argument
18
9
  // tableData = [ ['#username', 'tomsmith'], ['#password', '...'] ]
@@ -24,20 +15,20 @@ const test_1 = require("@playwright/test");
24
15
  const selector = row[0];
25
16
  const value = row[1];
26
17
  if (value === "click") {
27
- yield page.click(selector);
18
+ await page.click(selector);
28
19
  }
29
20
  else if (value === "check") {
30
- yield page.check(selector);
21
+ await page.check(selector);
31
22
  }
32
23
  else if (value === "assert:visible") {
33
- yield (0, test_1.expect)(page.locator(selector)).toBeVisible();
24
+ await (0, test_1.expect)(page.locator(selector)).toBeVisible();
34
25
  }
35
26
  else if (value.startsWith("assert:text:")) {
36
27
  const text = value.replace("assert:text:", "");
37
- yield (0, test_1.expect)(page.locator(selector)).toHaveText(text);
28
+ await (0, test_1.expect)(page.locator(selector)).toHaveText(text);
38
29
  }
39
30
  else {
40
- yield page.fill(selector, value);
31
+ await page.fill(selector, value);
41
32
  }
42
33
  }
43
- }));
34
+ });
@@ -1,32 +1,23 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const registry_1 = require("../../core/registry");
13
4
  // Click
14
- (0, registry_1.Step)("I click {string}", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
15
- yield page.click(selector);
16
- }));
5
+ (0, registry_1.Step)("I click {string}", async (page, selector) => {
6
+ await page.click(selector);
7
+ });
17
8
  // Force Click (sometimes needed for stubborn elements)
18
- (0, registry_1.Step)("I force click {string}", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
19
- yield page.click(selector, { force: true });
20
- }));
9
+ (0, registry_1.Step)("I force click {string}", async (page, selector) => {
10
+ await page.click(selector, { force: true });
11
+ });
21
12
  // Type/Fill
22
- (0, registry_1.Step)("I fill {string} with {string}", (page, selector, value) => __awaiter(void 0, void 0, void 0, function* () {
23
- yield page.fill(selector, value);
24
- }));
13
+ (0, registry_1.Step)("I fill {string} with {string}", async (page, selector, value) => {
14
+ await page.fill(selector, value);
15
+ });
25
16
  // Press Key (e.g., "Enter")
26
- (0, registry_1.Step)("I press {string}", (page, key) => __awaiter(void 0, void 0, void 0, function* () {
27
- yield page.keyboard.press(key);
28
- }));
17
+ (0, registry_1.Step)("I press {string}", async (page, key) => {
18
+ await page.keyboard.press(key);
19
+ });
29
20
  // Wait (Hard wait - use sparingly!)
30
- (0, registry_1.Step)("I wait for {int} milliseconds", (page, ms) => __awaiter(void 0, void 0, void 0, function* () {
31
- yield page.waitForTimeout(ms);
32
- }));
21
+ (0, registry_1.Step)("I wait for {int} milliseconds", async (page, ms) => {
22
+ await page.waitForTimeout(ms);
23
+ });
@@ -1,28 +1,19 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const registry_1 = require("../../core/registry");
13
4
  // Basic visit
14
- (0, registry_1.Step)("I visit {string}", (page, url) => __awaiter(void 0, void 0, void 0, function* () {
15
- yield page.goto(url);
16
- }));
5
+ (0, registry_1.Step)("I visit {string}", async (page, url) => {
6
+ await page.goto(url);
7
+ });
17
8
  // Visit and wait for network (useful for slow apps)
18
- (0, registry_1.Step)("I visit {string} and wait for network idle", (page, url) => __awaiter(void 0, void 0, void 0, function* () {
19
- yield page.goto(url, { waitUntil: "networkidle" });
20
- }));
9
+ (0, registry_1.Step)("I visit {string} and wait for network idle", async (page, url) => {
10
+ await page.goto(url, { waitUntil: "networkidle" });
11
+ });
21
12
  // Reload page
22
- (0, registry_1.Step)("I reload the page", (page) => __awaiter(void 0, void 0, void 0, function* () {
23
- yield page.reload();
24
- }));
13
+ (0, registry_1.Step)("I reload the page", async (page) => {
14
+ await page.reload();
15
+ });
25
16
  // Go back
26
- (0, registry_1.Step)("I go back", (page) => __awaiter(void 0, void 0, void 0, function* () {
27
- yield page.goBack();
28
- }));
17
+ (0, registry_1.Step)("I go back", async (page) => {
18
+ await page.goBack();
19
+ });
@@ -1,35 +1,26 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const test_1 = require("@playwright/test");
13
4
  const registry_1 = require("../../core/registry");
14
5
  const state_1 = require("./state");
15
6
  // Check Status Code
16
- (0, registry_1.Step)("I expect the response status to be {int}", (page, statusCode) => __awaiter(void 0, void 0, void 0, function* () {
7
+ (0, registry_1.Step)("I expect the response status to be {int}", async (page, statusCode) => {
17
8
  const response = state_1.apiState.getResponse();
18
9
  (0, test_1.expect)(response.status()).toBe(statusCode);
19
- }));
10
+ });
20
11
  // Check entire Body Text
21
- (0, registry_1.Step)("I expect the response body to contain {string}", (page, text) => __awaiter(void 0, void 0, void 0, function* () {
12
+ (0, registry_1.Step)("I expect the response body to contain {string}", async (page, text) => {
22
13
  const response = state_1.apiState.getResponse();
23
- const body = yield response.text();
14
+ const body = await response.text();
24
15
  (0, test_1.expect)(body).toContain(text);
25
- }));
16
+ });
26
17
  // Check JSON Property
27
- (0, registry_1.Step)("I expect the response property {string} to be {string}", (page, jsonPath, value) => __awaiter(void 0, void 0, void 0, function* () {
18
+ (0, registry_1.Step)("I expect the response property {string} to be {string}", async (page, jsonPath, value) => {
28
19
  const response = state_1.apiState.getResponse();
29
- const json = yield response.json();
20
+ const json = await response.json();
30
21
  // FIX: Added ': string' to the 'i' parameter
31
22
  const actualValue = jsonPath
32
23
  .split(".")
33
24
  .reduce((o, i) => o[i], json);
34
25
  (0, test_1.expect)(String(actualValue)).toBe(value);
35
- }));
26
+ });
@@ -32,53 +32,44 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
35
  Object.defineProperty(exports, "__esModule", { value: true });
45
36
  const registry_1 = require("../../core/registry");
46
37
  const fs = __importStar(require("fs"));
47
38
  const path = __importStar(require("path"));
48
39
  // 1. Mock with Inline JSON
49
40
  // Usage: Given I mock the API endpoint "/api/users" with body '{"id": 1, "name": "Fake"}'
50
- (0, registry_1.Step)("I mock the API endpoint {string} with body {string}", (page, urlPattern, jsonBody) => __awaiter(void 0, void 0, void 0, function* () {
51
- yield page.route(urlPattern, (route) => __awaiter(void 0, void 0, void 0, function* () {
41
+ (0, registry_1.Step)("I mock the API endpoint {string} with body {string}", async (page, urlPattern, jsonBody) => {
42
+ await page.route(urlPattern, async (route) => {
52
43
  const json = JSON.parse(jsonBody);
53
- yield route.fulfill({
44
+ await route.fulfill({
54
45
  status: 200,
55
46
  contentType: "application/json",
56
47
  body: JSON.stringify(json),
57
48
  });
58
- }));
49
+ });
59
50
  console.log(`🎭 Mocked ${urlPattern} with inline JSON`);
60
- }));
51
+ });
61
52
  // 2. Mock with File
62
53
  // Usage: Given I mock the API endpoint "/api/users" with response from "mocks/users.json"
63
- (0, registry_1.Step)("I mock the API endpoint {string} with response from {string}", (page, urlPattern, filePath) => __awaiter(void 0, void 0, void 0, function* () {
54
+ (0, registry_1.Step)("I mock the API endpoint {string} with response from {string}", async (page, urlPattern, filePath) => {
64
55
  const fullPath = path.resolve(process.cwd(), filePath);
65
56
  if (!fs.existsSync(fullPath)) {
66
57
  throw new Error(`❌ Mock file not found at: ${fullPath}`);
67
58
  }
68
59
  const bodyContent = fs.readFileSync(fullPath, "utf8");
69
- yield page.route(urlPattern, (route) => __awaiter(void 0, void 0, void 0, function* () {
70
- yield route.fulfill({
60
+ await page.route(urlPattern, async (route) => {
61
+ await route.fulfill({
71
62
  status: 200,
72
63
  contentType: "application/json",
73
64
  body: bodyContent,
74
65
  });
75
- }));
66
+ });
76
67
  console.log(`🎭 Mocked ${urlPattern} with file: ${filePath}`);
77
- }));
68
+ });
78
69
  // 3. Mock Status Code Only (Simulate Errors)
79
70
  // Usage: Given I mock the API endpoint "/api/broken" with status 500
80
- (0, registry_1.Step)("I mock the API endpoint {string} with status {int}", (page, urlPattern, statusCode) => __awaiter(void 0, void 0, void 0, function* () {
81
- yield page.route(urlPattern, (route) => __awaiter(void 0, void 0, void 0, function* () {
82
- yield route.fulfill({ status: statusCode });
83
- }));
84
- }));
71
+ (0, registry_1.Step)("I mock the API endpoint {string} with status {int}", async (page, urlPattern, statusCode) => {
72
+ await page.route(urlPattern, async (route) => {
73
+ await route.fulfill({ status: statusCode });
74
+ });
75
+ });
@@ -32,37 +32,28 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
35
  Object.defineProperty(exports, "__esModule", { value: true });
45
36
  const registry_1 = require("../../core/registry");
46
37
  const state_1 = require("./state");
47
38
  const fs = __importStar(require("fs"));
48
39
  const path = __importStar(require("path"));
49
40
  // GET Request
50
- (0, registry_1.Step)("I make a GET request to {string}", (page, url) => __awaiter(void 0, void 0, void 0, function* () {
51
- const response = yield page.request.get(url);
41
+ (0, registry_1.Step)("I make a GET request to {string}", async (page, url) => {
42
+ const response = await page.request.get(url);
52
43
  state_1.apiState.setResponse(response);
53
44
  console.log(`GET ${url} - Status: ${response.status()}`);
54
- }));
45
+ });
55
46
  // DELETE Request
56
- (0, registry_1.Step)("I make a DELETE request to {string}", (page, url) => __awaiter(void 0, void 0, void 0, function* () {
57
- const response = yield page.request.delete(url);
47
+ (0, registry_1.Step)("I make a DELETE request to {string}", async (page, url) => {
48
+ const response = await page.request.delete(url);
58
49
  state_1.apiState.setResponse(response);
59
- }));
50
+ });
60
51
  // 1. POST with Data Table
61
52
  // Usage:
62
53
  // When I make a POST request to "/api/users" with data:
63
54
  // | name | John |
64
55
  // | job | Dev |
65
- (0, registry_1.Step)("I make a POST request to {string} with data", (page, url, tableData) => __awaiter(void 0, void 0, void 0, function* () {
56
+ (0, registry_1.Step)("I make a POST request to {string} with data", async (page, url, tableData) => {
66
57
  if (!tableData)
67
58
  throw new Error("This step requires a Data Table.");
68
59
  // Convert Table [ ["key", "val"], ["k2", "v2"] ] -> Object { key: "val", k2: "v2" }
@@ -70,15 +61,15 @@ const path = __importStar(require("path"));
70
61
  acc[row[0]] = row[1];
71
62
  return acc;
72
63
  }, {});
73
- const response = yield page.request.post(url, {
64
+ const response = await page.request.post(url, {
74
65
  data: payload,
75
66
  headers: { "Content-Type": "application/json" },
76
67
  });
77
68
  state_1.apiState.setResponse(response);
78
- }));
69
+ });
79
70
  // 2. POST with File Payload
80
71
  // Usage: When I make a POST request to "/api/users" with payload from "data/user.json"
81
- (0, registry_1.Step)("I make a POST request to {string} with payload from {string}", (page, url, filePath) => __awaiter(void 0, void 0, void 0, function* () {
72
+ (0, registry_1.Step)("I make a POST request to {string} with payload from {string}", async (page, url, filePath) => {
82
73
  // Resolve file path (relative to root)
83
74
  const fullPath = path.resolve(process.cwd(), filePath);
84
75
  if (!fs.existsSync(fullPath)) {
@@ -87,9 +78,9 @@ const path = __importStar(require("path"));
87
78
  // Read and parse JSON
88
79
  const fileContent = fs.readFileSync(fullPath, "utf8");
89
80
  const payload = JSON.parse(fileContent);
90
- const response = yield page.request.post(url, {
81
+ const response = await page.request.post(url, {
91
82
  data: payload,
92
83
  headers: { "Content-Type": "application/json" },
93
84
  });
94
85
  state_1.apiState.setResponse(response);
95
- }));
86
+ });
@@ -1,19 +1,8 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.expectVisible = expectVisible;
13
- function expectVisible(page_1, selector_1) {
14
- return __awaiter(this, arguments, void 0, function* (page, selector, timeout = 2000) {
15
- const el = yield page.waitForSelector(selector, { state: 'visible', timeout });
16
- if (!el)
17
- throw new Error(`Element ${selector} not visible`);
18
- });
4
+ async function expectVisible(page, selector, timeout = 2000) {
5
+ const el = await page.waitForSelector(selector, { state: 'visible', timeout });
6
+ if (!el)
7
+ throw new Error(`Element ${selector} not visible`);
19
8
  }
@@ -1,34 +1,25 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const test_1 = require("@playwright/test");
13
4
  const registry_1 = require("../../core/registry");
14
5
  // URL Check
15
- (0, registry_1.Step)("I expect the url to be {string}", (page, url) => __awaiter(void 0, void 0, void 0, function* () {
16
- yield (0, test_1.expect)(page).toHaveURL(url);
17
- }));
6
+ (0, registry_1.Step)("I expect the url to be {string}", async (page, url) => {
7
+ await (0, test_1.expect)(page).toHaveURL(url);
8
+ });
18
9
  // Partial URL Check
19
- (0, registry_1.Step)("I expect the url to contain {string}", (page, part) => __awaiter(void 0, void 0, void 0, function* () {
10
+ (0, registry_1.Step)("I expect the url to contain {string}", async (page, part) => {
20
11
  // We use a RegExp to allow partial matching safely
21
- yield (0, test_1.expect)(page).toHaveURL(new RegExp(part));
22
- }));
12
+ await (0, test_1.expect)(page).toHaveURL(new RegExp(part));
13
+ });
23
14
  // Title Check
24
- (0, registry_1.Step)("I expect the title to be {string}", (page, title) => __awaiter(void 0, void 0, void 0, function* () {
25
- yield (0, test_1.expect)(page).toHaveTitle(title);
26
- }));
15
+ (0, registry_1.Step)("I expect the title to be {string}", async (page, title) => {
16
+ await (0, test_1.expect)(page).toHaveTitle(title);
17
+ });
27
18
  // Partial Title Check
28
- (0, registry_1.Step)("I expect the title to contain {string}", (page, titlePart) => __awaiter(void 0, void 0, void 0, function* () {
29
- yield (0, test_1.expect)(page).toHaveTitle(new RegExp(titlePart));
30
- }));
19
+ (0, registry_1.Step)("I expect the title to contain {string}", async (page, titlePart) => {
20
+ await (0, test_1.expect)(page).toHaveTitle(new RegExp(titlePart));
21
+ });
31
22
  // Screenshot Match (Visual Regression)
32
- (0, registry_1.Step)("I expect the page screenshot to match {string}", (page, filename) => __awaiter(void 0, void 0, void 0, function* () {
33
- yield (0, test_1.expect)(page).toHaveScreenshot(filename);
34
- }));
23
+ (0, registry_1.Step)("I expect the page screenshot to match {string}", async (page, filename) => {
24
+ await (0, test_1.expect)(page).toHaveScreenshot(filename);
25
+ });
@@ -1,29 +1,20 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const test_1 = require("@playwright/test");
13
4
  const registry_1 = require("../../core/registry");
14
5
  // Exact text match
15
- (0, registry_1.Step)("I expect {string} to have text {string}", (page, selector, text) => __awaiter(void 0, void 0, void 0, function* () {
16
- yield (0, test_1.expect)(page.locator(selector)).toHaveText(text);
17
- }));
6
+ (0, registry_1.Step)("I expect {string} to have text {string}", async (page, selector, text) => {
7
+ await (0, test_1.expect)(page.locator(selector)).toHaveText(text);
8
+ });
18
9
  // Partial text match (contains)
19
- (0, registry_1.Step)("I expect {string} to contain text {string}", (page, selector, text) => __awaiter(void 0, void 0, void 0, function* () {
20
- yield (0, test_1.expect)(page.locator(selector)).toContainText(text);
21
- }));
10
+ (0, registry_1.Step)("I expect {string} to contain text {string}", async (page, selector, text) => {
11
+ await (0, test_1.expect)(page.locator(selector)).toContainText(text);
12
+ });
22
13
  // Check input value (for form fields)
23
- (0, registry_1.Step)("I expect {string} to have value {string}", (page, selector, value) => __awaiter(void 0, void 0, void 0, function* () {
24
- yield (0, test_1.expect)(page.locator(selector)).toHaveValue(value);
25
- }));
14
+ (0, registry_1.Step)("I expect {string} to have value {string}", async (page, selector, value) => {
15
+ await (0, test_1.expect)(page.locator(selector)).toHaveValue(value);
16
+ });
26
17
  // Check an attribute (e.g., class, href, src)
27
- (0, registry_1.Step)("I expect {string} to have attribute {string} with value {string}", (page, selector, attr, value) => __awaiter(void 0, void 0, void 0, function* () {
28
- yield (0, test_1.expect)(page.locator(selector)).toHaveAttribute(attr, value);
29
- }));
18
+ (0, registry_1.Step)("I expect {string} to have attribute {string} with value {string}", async (page, selector, attr, value) => {
19
+ await (0, test_1.expect)(page.locator(selector)).toHaveAttribute(attr, value);
20
+ });
@@ -1,29 +1,20 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const test_1 = require("@playwright/test");
13
4
  const registry_1 = require("../../core/registry");
14
5
  // Check if element exists and is visible
15
- (0, registry_1.Step)("I expect {string} to be visible", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
16
- yield (0, test_1.expect)(page.locator(selector)).toBeVisible();
17
- }));
6
+ (0, registry_1.Step)("I expect {string} to be visible", async (page, selector) => {
7
+ await (0, test_1.expect)(page.locator(selector)).toBeVisible();
8
+ });
18
9
  // Check if element is hidden (or doesn't exist)
19
- (0, registry_1.Step)("I expect {string} to be hidden", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
20
- yield (0, test_1.expect)(page.locator(selector)).toBeHidden();
21
- }));
10
+ (0, registry_1.Step)("I expect {string} to be hidden", async (page, selector) => {
11
+ await (0, test_1.expect)(page.locator(selector)).toBeHidden();
12
+ });
22
13
  // Check if element is enabled (clickable)
23
- (0, registry_1.Step)("I expect {string} to be enabled", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
24
- yield (0, test_1.expect)(page.locator(selector)).toBeEnabled();
25
- }));
14
+ (0, registry_1.Step)("I expect {string} to be enabled", async (page, selector) => {
15
+ await (0, test_1.expect)(page.locator(selector)).toBeEnabled();
16
+ });
26
17
  // Check if element is disabled
27
- (0, registry_1.Step)("I expect {string} to be disabled", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
28
- yield (0, test_1.expect)(page.locator(selector)).toBeDisabled();
29
- }));
18
+ (0, registry_1.Step)("I expect {string} to be disabled", async (page, selector) => {
19
+ await (0, test_1.expect)(page.locator(selector)).toBeDisabled();
20
+ });
@@ -32,34 +32,25 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
35
  Object.defineProperty(exports, "__esModule", { value: true });
45
36
  const registry_1 = require("../../core/registry");
46
37
  const path = __importStar(require("path"));
47
38
  const fs = __importStar(require("fs"));
48
39
  // 1. SAVE STATE (Use this after a successful login)
49
40
  // Example: And I save the browser state to "admin.json"
50
- (0, registry_1.Step)("I save the browser state to {string}", (page, filename) => __awaiter(void 0, void 0, void 0, function* () {
41
+ (0, registry_1.Step)("I save the browser state to {string}", async (page, filename) => {
51
42
  // Ensure the directory exists
52
43
  const authDir = path.resolve(process.cwd(), "auth");
53
44
  if (!fs.existsSync(authDir)) {
54
45
  fs.mkdirSync(authDir);
55
46
  }
56
47
  const filePath = path.resolve(authDir, filename);
57
- yield page.context().storageState({ path: filePath });
48
+ await page.context().storageState({ path: filePath });
58
49
  console.log(`✅ State saved to: ${filePath}`);
59
- }));
50
+ });
60
51
  // 2. LOAD STATE (Use this at the start of other scenarios)
61
52
  // Example: Given I load the browser state from "admin.json"
62
- (0, registry_1.Step)("I load the browser state from {string}", (page, filename) => __awaiter(void 0, void 0, void 0, function* () {
53
+ (0, registry_1.Step)("I load the browser state from {string}", async (page, filename) => {
63
54
  const filePath = path.resolve(process.cwd(), "auth", filename);
64
55
  if (!fs.existsSync(filePath)) {
65
56
  throw new Error(`❌ Auth file not found at: ${filePath}. Did you run the login scenario first?`);
@@ -68,7 +59,7 @@ const fs = __importStar(require("fs"));
68
59
  // To load it dynamically mid-test, we need to add cookies/origins to the current context.
69
60
  const state = JSON.parse(fs.readFileSync(filePath, "utf8"));
70
61
  if (state.cookies) {
71
- yield page.context().addCookies(state.cookies);
62
+ await page.context().addCookies(state.cookies);
72
63
  }
73
64
  if (state.origins) {
74
65
  // LocalStorage requires a bit more work, usually handled by context creation,
@@ -77,4 +68,4 @@ const fs = __importStar(require("fs"));
77
68
  // but this step is a great dynamic helper.
78
69
  }
79
70
  console.log(`✅ Loaded session for: ${filename}`);
80
- }));
71
+ });
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.dbState = void 0;
13
4
  // Holds the user's custom DB function
@@ -19,15 +10,15 @@ exports.dbState = {
19
10
  dbAdapter = fn;
20
11
  },
21
12
  // Step calls this to run a query
22
- executeQuery: (query) => __awaiter(void 0, void 0, void 0, function* () {
13
+ executeQuery: async (query) => {
23
14
  if (!dbAdapter) {
24
15
  throw new Error("❌ No Database Adapter found. Pass a 'dbQuery' function to runTests().");
25
16
  }
26
- const result = yield dbAdapter(query);
17
+ const result = await dbAdapter(query);
27
18
  lastResult = result;
28
19
  console.log(`🗄️ DB Result:`, JSON.stringify(lastResult));
29
20
  return result;
30
- }),
21
+ },
31
22
  // Assertions use this to check results
32
23
  getLastResult: () => lastResult,
33
24
  };
@@ -1,23 +1,14 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const registry_1 = require("../../core/registry");
13
4
  const state_1 = require("./state");
14
5
  const test_1 = require("@playwright/test");
15
6
  // 1. Run Query
16
- (0, registry_1.Step)("I run the database query {string}", (page, query) => __awaiter(void 0, void 0, void 0, function* () {
17
- yield state_1.dbState.executeQuery(query);
18
- }));
7
+ (0, registry_1.Step)("I run the database query {string}", async (page, query) => {
8
+ await state_1.dbState.executeQuery(query);
9
+ });
19
10
  // 2. Count Check
20
- (0, registry_1.Step)("I expect the database to return {int} record(s)", (page, count) => __awaiter(void 0, void 0, void 0, function* () {
11
+ (0, registry_1.Step)("I expect the database to return {int} record(s)", async (page, count) => {
21
12
  const result = state_1.dbState.getLastResult();
22
13
  if (Array.isArray(result)) {
23
14
  (0, test_1.expect)(result.length).toBe(count);
@@ -25,10 +16,10 @@ const test_1 = require("@playwright/test");
25
16
  else {
26
17
  throw new Error(`Expected array result but got: ${typeof result}`);
27
18
  }
28
- }));
19
+ });
29
20
  // 3. JSON/Table Check
30
21
  // CHANGE: Removed the colon ':' at the end of the string below
31
- (0, registry_1.Step)("I expect the first database record to contain", (page, tableData) => __awaiter(void 0, void 0, void 0, function* () {
22
+ (0, registry_1.Step)("I expect the first database record to contain", async (page, tableData) => {
32
23
  const result = state_1.dbState.getLastResult();
33
24
  // Guard Clauses
34
25
  if (!Array.isArray(result) || result.length === 0) {
@@ -49,4 +40,4 @@ const test_1 = require("@playwright/test");
49
40
  // Loose equality check (DB might return int, Gherkin sends string)
50
41
  (0, test_1.expect)(String(firstRow[key])).toBe(expectedValue);
51
42
  }
52
- }));
43
+ });
@@ -1,30 +1,21 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const registry_1 = require("../../core/registry");
13
4
  // Accept the next popup (Alert/Confirm/Prompt)
14
- (0, registry_1.Step)("I accept the next dialog", (page) => __awaiter(void 0, void 0, void 0, function* () {
15
- page.once("dialog", (dialog) => __awaiter(void 0, void 0, void 0, function* () {
16
- yield dialog.accept();
17
- }));
18
- }));
5
+ (0, registry_1.Step)("I accept the next dialog", async (page) => {
6
+ page.once("dialog", async (dialog) => {
7
+ await dialog.accept();
8
+ });
9
+ });
19
10
  // Dismiss (Cancel) the next popup
20
- (0, registry_1.Step)("I dismiss the next dialog", (page) => __awaiter(void 0, void 0, void 0, function* () {
21
- page.once("dialog", (dialog) => __awaiter(void 0, void 0, void 0, function* () {
22
- yield dialog.dismiss();
23
- }));
24
- }));
11
+ (0, registry_1.Step)("I dismiss the next dialog", async (page) => {
12
+ page.once("dialog", async (dialog) => {
13
+ await dialog.dismiss();
14
+ });
15
+ });
25
16
  // Type text into a prompt and accept
26
- (0, registry_1.Step)("I type {string} into the next prompt and accept", (page, text) => __awaiter(void 0, void 0, void 0, function* () {
27
- page.once("dialog", (dialog) => __awaiter(void 0, void 0, void 0, function* () {
28
- yield dialog.accept(text);
29
- }));
30
- }));
17
+ (0, registry_1.Step)("I type {string} into the next prompt and accept", async (page, text) => {
18
+ page.once("dialog", async (dialog) => {
19
+ await dialog.accept(text);
20
+ });
21
+ });
@@ -32,37 +32,28 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
35
  Object.defineProperty(exports, "__esModule", { value: true });
45
36
  const registry_1 = require("../../core/registry");
46
37
  const path = __importStar(require("path"));
47
38
  // Dropdown: Select by value or label
48
- (0, registry_1.Step)("I select option {string} from {string}", (page, option, selector) => __awaiter(void 0, void 0, void 0, function* () {
49
- yield page.selectOption(selector, { label: option }).catch(() => {
39
+ (0, registry_1.Step)("I select option {string} from {string}", async (page, option, selector) => {
40
+ await page.selectOption(selector, { label: option }).catch(() => {
50
41
  // Fallback: try selecting by value if label fails
51
42
  return page.selectOption(selector, { value: option });
52
43
  });
53
- }));
44
+ });
54
45
  // Checkboxes & Radio Buttons
55
- (0, registry_1.Step)("I check {string}", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
56
- yield page.check(selector);
57
- }));
58
- (0, registry_1.Step)("I uncheck {string}", (page, selector) => __awaiter(void 0, void 0, void 0, function* () {
59
- yield page.uncheck(selector);
60
- }));
46
+ (0, registry_1.Step)("I check {string}", async (page, selector) => {
47
+ await page.check(selector);
48
+ });
49
+ (0, registry_1.Step)("I uncheck {string}", async (page, selector) => {
50
+ await page.uncheck(selector);
51
+ });
61
52
  // File Upload
62
53
  // Usage: When I upload file "data.csv" to "#upload-input"
63
- (0, registry_1.Step)("I upload file {string} to {string}", (page, fileName, selector) => __awaiter(void 0, void 0, void 0, function* () {
54
+ (0, registry_1.Step)("I upload file {string} to {string}", async (page, fileName, selector) => {
64
55
  // We assume the user puts files in a 'fixtures' or root folder.
65
56
  // You might want to customize this path resolution.
66
57
  const filePath = path.resolve(process.cwd(), fileName);
67
- yield page.setInputFiles(selector, filePath);
68
- }));
58
+ await page.setInputFiles(selector, filePath);
59
+ });
@@ -1,34 +1,25 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const registry_1 = require("../../core/registry");
13
4
  // Click inside a specific frame
14
- (0, registry_1.Step)("I click {string} inside frame {string}", (page, elementSelector, frameSelector) => __awaiter(void 0, void 0, void 0, function* () {
5
+ (0, registry_1.Step)("I click {string} inside frame {string}", async (page, elementSelector, frameSelector) => {
15
6
  const frame = page.frameLocator(frameSelector);
16
- yield frame.locator(elementSelector).click();
17
- }));
7
+ await frame.locator(elementSelector).click();
8
+ });
18
9
  // Fill input inside a specific frame
19
- (0, registry_1.Step)("I fill {string} inside frame {string} with {string}", (page, elementSelector, frameSelector, value) => __awaiter(void 0, void 0, void 0, function* () {
10
+ (0, registry_1.Step)("I fill {string} inside frame {string} with {string}", async (page, elementSelector, frameSelector, value) => {
20
11
  const frame = page.frameLocator(frameSelector);
21
- yield frame.locator(elementSelector).fill(value);
22
- }));
12
+ await frame.locator(elementSelector).fill(value);
13
+ });
23
14
  // Assert text inside a specific frame
24
- (0, registry_1.Step)("I expect {string} inside frame {string} to have text {string}", (page, elementSelector, frameSelector, text) => __awaiter(void 0, void 0, void 0, function* () {
15
+ (0, registry_1.Step)("I expect {string} inside frame {string} to have text {string}", async (page, elementSelector, frameSelector, text) => {
25
16
  const frame = page.frameLocator(frameSelector);
26
17
  const locator = frame.locator(elementSelector);
27
18
  // We need to import expect for this assertion, or use a custom check
28
19
  // Since we are inside 'elements', let's just do a basic wait/check or re-export expect
29
- yield locator.waitFor();
30
- const actualText = yield locator.textContent();
31
- if (!(actualText === null || actualText === void 0 ? void 0 : actualText.includes(text))) {
20
+ await locator.waitFor();
21
+ const actualText = await locator.textContent();
22
+ if (!actualText?.includes(text)) {
32
23
  throw new Error(`Expected text "${text}" but found "${actualText}" in frame`);
33
24
  }
34
- }));
25
+ });
@@ -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,QA8GpE"}
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,QAiIpE"}
@@ -32,15 +32,6 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
35
  Object.defineProperty(exports, "__esModule", { value: true });
45
36
  exports.runTests = runTests;
46
37
  // src/core/runner.ts
@@ -62,10 +53,15 @@ require("../backend/db/index"); // Register DB steps
62
53
  */
63
54
  function runTests(featureGlob, options) {
64
55
  // 1. Register DB Adapter if provided
65
- if (options === null || options === void 0 ? void 0 : options.dbQuery) {
56
+ if (options?.dbQuery) {
66
57
  state_1.dbState.setAdapter(options.dbQuery);
67
58
  }
59
+ // Debugging: Verify files are found to help user troubleshoot paths
68
60
  const files = (0, glob_1.globSync)(featureGlob);
61
+ if (files.length === 0) {
62
+ console.warn(`⚠️ No Feature files found matching: "${featureGlob}"`);
63
+ console.warn(` Current Directory: ${process.cwd()}`);
64
+ }
69
65
  for (const file of files) {
70
66
  const content = fs.readFileSync(file, "utf8");
71
67
  const featureMatch = content.match(/Feature:\s*(.+)/);
@@ -73,9 +69,14 @@ function runTests(featureGlob, options) {
73
69
  ? featureMatch[1].trim()
74
70
  : "Unnamed Feature";
75
71
  test_1.test.describe(featureName, () => {
76
- const scenarioRegex = /(?:(@[\w\s@]+)\s+)?Scenario:\s*(.+)/g;
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)
75
+ const scenarioRegex = /(?:(@[^:\r\n]+)\s+)?Scenario:\s*(.+)/g;
77
76
  let match;
77
+ let scenarioCount = 0;
78
78
  while ((match = scenarioRegex.exec(content)) !== null) {
79
+ scenarioCount++;
79
80
  // 1. CAPTURE DATA IMMEDIATELY
80
81
  const foundTags = match[1] || "";
81
82
  const scenarioName = match[2].trim();
@@ -83,10 +84,10 @@ function runTests(featureGlob, options) {
83
84
  const nextMatchIndex = content.slice(startIndex).search(/Scenario:/);
84
85
  const blockEnd = nextMatchIndex === -1 ? content.length : startIndex + nextMatchIndex;
85
86
  const scenarioBlock = content.slice(startIndex, blockEnd);
86
- if ((options === null || options === void 0 ? void 0 : options.tags) && !foundTags.includes(options.tags)) {
87
+ if (options?.tags && !foundTags.includes(options.tags)) {
87
88
  continue;
88
89
  }
89
- (0, test_1.test)(scenarioName, (_a, testInfo_1) => __awaiter(this, [_a, testInfo_1], void 0, function* ({ page }, testInfo) {
90
+ (0, test_1.test)(scenarioName, async ({ page }, testInfo) => {
90
91
  const lines = scenarioBlock
91
92
  .trim()
92
93
  .split("\n")
@@ -128,23 +129,27 @@ function runTests(featureGlob, options) {
128
129
  args.push(tableData);
129
130
  }
130
131
  // Pass 'page' + args to the step function
131
- yield stepDef.fn(page, ...args);
132
+ await stepDef.fn(page, ...args);
132
133
  }
133
134
  catch (error) {
134
135
  console.error(`❌ Failed at step: "${stepText}"`);
135
136
  // Take a screenshot immediately
136
- const screenshot = yield page.screenshot({
137
+ const screenshot = await page.screenshot({
137
138
  fullPage: true,
138
139
  type: "png",
139
140
  });
140
- yield testInfo.attach("failure-screenshot", {
141
+ await testInfo.attach("failure-screenshot", {
141
142
  body: screenshot,
142
143
  contentType: "image/png",
143
144
  });
144
145
  throw error;
145
146
  }
146
147
  }
147
- }));
148
+ });
149
+ }
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.`);
148
153
  }
149
154
  });
150
155
  }
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.0.6",
4
+ "version": "1.0.8",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",