playwright-cucumber-ts-steps 0.0.9 โ†’ 0.1.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.
@@ -84,16 +84,14 @@ When(/^I screenshot "(.*)"$/, async function (name) {
84
84
  });
85
85
  });
86
86
  When("I screenshot", async function () {
87
- var _a;
88
87
  const path = `screenshots/screenshot-${Date.now()}.png`;
89
88
  await this.page.screenshot({ path, fullPage: true });
90
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `Saved screenshot to ${path}`);
89
+ this.log?.(`Saved screenshot to ${path}`);
91
90
  });
92
91
  //
93
92
  // Page Navigation
94
93
  //
95
94
  When("I visit {string}", async function (urlOrAlias) {
96
- var _a;
97
95
  let url = urlOrAlias;
98
96
  if (url.startsWith("@")) {
99
97
  const alias = url.substring(1);
@@ -107,7 +105,7 @@ When("I visit {string}", async function (urlOrAlias) {
107
105
  throw new Error("BASE_URL not defined");
108
106
  url = `${baseUrl.replace(/\/+$/, "")}${url}`;
109
107
  }
110
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `Visiting: ${url}`);
108
+ this.log?.(`Visiting: ${url}`);
111
109
  await this.page.goto(url);
112
110
  });
113
111
  When("I reload the page", async function () {
@@ -142,8 +140,7 @@ const validUnits = [
142
140
  "years",
143
141
  ];
144
142
  When('I store {string} {int} {word} {word} as "{word}"', async function (baseAlias, amount, unit, direction, newAlias) {
145
- var _a, _b;
146
- const baseDateRaw = (_a = this.data) === null || _a === void 0 ? void 0 : _a[baseAlias];
143
+ const baseDateRaw = this.data?.[baseAlias];
147
144
  if (!baseDateRaw)
148
145
  throw new Error(`Alias "${baseAlias}" not found`);
149
146
  if (!validUnits.includes(unit))
@@ -154,35 +151,32 @@ When('I store {string} {int} {word} {word} as "{word}"', async function (baseAli
154
151
  const result = baseDate[direction === "before" ? "subtract" : "add"](amount, unit);
155
152
  const formatted = result.format("YYYY-MM-DD");
156
153
  this.data[newAlias] = formatted;
157
- (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, `๐Ÿ“… Stored ${amount} ${unit} ${direction} "${baseAlias}" as "@${newAlias}" = ${formatted}`);
154
+ this.log?.(`๐Ÿ“… Stored ${amount} ${unit} ${direction} "${baseAlias}" as "@${newAlias}" = ${formatted}`);
158
155
  });
159
156
  //
160
157
  // IFrame
161
158
  //
162
159
  When("I switch to iframe with selector {string}", async function (selector) {
163
- var _a;
164
160
  const frameLocator = this.page.frameLocator(selector);
165
161
  await frameLocator
166
162
  .locator("body")
167
163
  .waitFor({ state: "visible", timeout: 10000 });
168
164
  this.frame = frameLocator;
169
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐ŸชŸ Switched to iframe: ${selector}`);
165
+ this.log?.(`๐ŸชŸ Switched to iframe: ${selector}`);
170
166
  });
171
167
  When("I switch to iframe with title {string}", async function (title) {
172
- var _a;
173
168
  const frames = this.page.frames();
174
169
  const match = frames.find((f) => f.title().then((t) => t.includes(title)));
175
170
  if (!match)
176
171
  throw new Error(`No iframe with title "${title}"`);
177
172
  this.frame = this.page.frameLocator(`iframe[title*="${title}"]`);
178
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐ŸชŸ Switched to iframe titled: ${title}`);
173
+ this.log?.(`๐ŸชŸ Switched to iframe titled: ${title}`);
179
174
  });
180
175
  When("I switch to iframe with selector {string} and wait for text {string}", async function (selector, expected) {
181
- var _a;
182
176
  const frameLocator = this.page.frameLocator(selector);
183
177
  await frameLocator.locator(`text=${expected}`).waitFor({ timeout: 10000 });
184
178
  this.frame = frameLocator;
185
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐ŸชŸ Switched to iframe: ${selector}, waited for "${expected}"`);
179
+ this.log?.(`๐ŸชŸ Switched to iframe: ${selector}, waited for "${expected}"`);
186
180
  });
187
181
  When("I exit iframe", function () {
188
182
  this.exitIframe();
@@ -207,8 +201,7 @@ async function getReadableLabel(el) {
207
201
  }
208
202
  }
209
203
  async function getElementsSubset(world, mode, count) {
210
- var _a;
211
- const total = await ((_a = world.elements) === null || _a === void 0 ? void 0 : _a.count());
204
+ const total = await world.elements?.count();
212
205
  if (!total || total < 1)
213
206
  throw new Error("No elements stored");
214
207
  if (count > total)
@@ -243,7 +236,6 @@ const locatorActions = {
243
236
  fill: (el, table) => el.fill("", parseFillOptions(table)), // Extend this to support value
244
237
  };
245
238
  When(/^I (\w+) the (first|last|random) (\d+)$/, async function (action, mode, count, table) {
246
- var _a;
247
239
  const elements = await getElementsSubset(this, mode, count);
248
240
  const actionFn = locatorActions[action];
249
241
  if (!actionFn)
@@ -251,11 +243,10 @@ When(/^I (\w+) the (first|last|random) (\d+)$/, async function (action, mode, co
251
243
  for (const el of elements) {
252
244
  const label = await getReadableLabel(el);
253
245
  await actionFn(el, table);
254
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `โœ… ${actionDisplayNames[action] || action} element: "${label}"`);
246
+ this.log?.(`โœ… ${actionDisplayNames[action] || action} element: "${label}"`);
255
247
  }
256
248
  });
257
249
  When(/^I (\w+) the (\d+)(?:st|nd|rd|th) element$/, async function (action, nth, table) {
258
- var _a;
259
250
  const elements = await getElementsSubset(this, "nth", nth);
260
251
  const actionFn = locatorActions[action];
261
252
  if (!actionFn)
@@ -263,15 +254,14 @@ When(/^I (\w+) the (\d+)(?:st|nd|rd|th) element$/, async function (action, nth,
263
254
  for (const el of elements) {
264
255
  const label = await getReadableLabel(el);
265
256
  await actionFn(el, table);
266
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `โœ… ${actionDisplayNames[action] || action} the ${toOrdinal(nth)} element: "${label}"`);
257
+ this.log?.(`โœ… ${actionDisplayNames[action] || action} the ${toOrdinal(nth)} element: "${label}"`);
267
258
  }
268
259
  });
269
260
  When("I press key {string}", async function (key) {
270
- var _a;
271
261
  if (!this.element)
272
262
  throw new Error("No element selected");
273
263
  await this.element.focus();
274
264
  await this.page.waitForTimeout(100); // buffer
275
265
  await this.element.press(key);
276
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐ŸŽน Pressed {${key}}`);
266
+ this.log?.(`๐ŸŽน Pressed {${key}}`);
277
267
  });
@@ -25,7 +25,6 @@ When(/^I scroll window to position top:(\d+) left:(\d+)$/, async function (top,
25
25
  }, top, left);
26
26
  });
27
27
  When('I scroll to "{word}"', async function (direction) {
28
- var _a;
29
28
  const validDirections = ["top", "bottom", "left", "right"];
30
29
  if (!validDirections.includes(direction)) {
31
30
  throw new Error(`Invalid scroll direction "${direction}". Must be one of: ${validDirections.join(", ")}.`);
@@ -50,18 +49,16 @@ When('I scroll to "{word}"', async function (direction) {
50
49
  }
51
50
  window.scrollTo(scrollOptions);
52
51
  }, direction);
53
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿ–ฑ๏ธ Scrolled to "${direction}"`);
52
+ this.log?.(`๐Ÿ–ฑ๏ธ Scrolled to "${direction}"`);
54
53
  await this.page.waitForTimeout(500); // allow scroll to complete
55
54
  });
56
55
  When("I hover over the element {string}", async function (selector) {
57
- var _a;
58
56
  const element = this.getScope().locator(selector);
59
57
  await element.hover();
60
58
  this.element = element;
61
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿ–ฑ๏ธ Hovered: ${selector}`);
59
+ this.log?.(`๐Ÿ–ฑ๏ธ Hovered: ${selector}`);
62
60
  });
63
61
  When("I move mouse to coordinates {int}, {int}", async function (x, y) {
64
- var _a;
65
62
  await this.page.mouse.move(x, y);
66
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿงญ Mouse moved to (${x}, ${y})`);
63
+ this.log?.(`๐Ÿงญ Mouse moved to (${x}, ${y})`);
67
64
  });
@@ -37,7 +37,6 @@ When("I clear local storage", async function () {
37
37
  await this.page.evaluate(() => localStorage.clear());
38
38
  });
39
39
  When("I store input text as {string}", async function (alias) {
40
- var _a;
41
40
  const activeElementHandle = await this.page.evaluateHandle(() => document.activeElement);
42
41
  const tagName = await activeElementHandle.evaluate((el) => el ? el.tagName.toLowerCase() : "");
43
42
  if (tagName !== "input" && tagName !== "textarea") {
@@ -45,5 +44,5 @@ When("I store input text as {string}", async function (alias) {
45
44
  }
46
45
  const value = await activeElementHandle.evaluate((el) => el.value);
47
46
  this.data[alias] = value;
48
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿ“ฅ Stored value from input as "${alias}": ${value}`);
47
+ this.log?.(`๐Ÿ“ฅ Stored value from input as "${alias}": ${value}`);
49
48
  });
@@ -52,11 +52,10 @@ Then(/^I do not see button "(.*)"$/, async function (rawText) {
52
52
  * THEN: I see text "Welcome"
53
53
  */
54
54
  Then("I see text {string}", async function (expected) {
55
- var _a;
56
55
  const scope = this.getScope(); // โœ… Supports iframe OR main page
57
56
  const locator = scope.locator(`text=${expected}`);
58
57
  await locator.waitFor({ state: "visible", timeout: 5000 });
59
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `โœ… Verified text visible: ${expected}`);
58
+ this.log?.(`โœ… Verified text visible: ${expected}`);
60
59
  });
61
60
  /**
62
61
  * THEN: I do not see text "Error"
@@ -118,7 +117,6 @@ Then(/^I do not see text "(.*)"$/, async function (unexpectedText) {
118
117
  // ๐Ÿ†• Visible Text - Alias for clarity (optional if you want separate steps for naming)
119
118
  //
120
119
  Then("I see {string} in the element", async function (expected) {
121
- var _a;
122
120
  const element = this.element;
123
121
  if (!element)
124
122
  throw new Error("No element selected");
@@ -135,10 +133,9 @@ Then("I see {string} in the element", async function (expected) {
135
133
  if (!textContent)
136
134
  throw new Error("Element has no text content");
137
135
  expect(textContent).toContain(expected);
138
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `Verified "${expected}" in element text`);
136
+ this.log?.(`Verified "${expected}" in element text`);
139
137
  });
140
138
  Then("I see @{word} in the element", async function (alias) {
141
- var _a;
142
139
  const storedValue = this.data[alias];
143
140
  if (!storedValue) {
144
141
  throw new Error(`No value found in data storage under alias "@${alias}".`);
@@ -146,12 +143,11 @@ Then("I see @{word} in the element", async function (alias) {
146
143
  if (!this.element) {
147
144
  throw new Error("No element found. You must get an element before asserting its contents.");
148
145
  }
149
- const actualText = ((_a = (await this.element.textContent())) === null || _a === void 0 ? void 0 : _a.trim()) || "";
146
+ const actualText = (await this.element.textContent())?.trim() || "";
150
147
  expect(actualText).toContain(storedValue);
151
148
  this.log(`Verified element contains value from "@${alias}" = "${storedValue}". Actual: "${actualText}"`);
152
149
  });
153
150
  Then("I see button {string} is disabled", async function (rawText) {
154
- var _a;
155
151
  // Resolve alias
156
152
  let buttonText = rawText.startsWith("@")
157
153
  ? this.data[rawText.slice(1)]
@@ -168,5 +164,5 @@ Then("I see button {string} is disabled", async function (rawText) {
168
164
  if (!isDisabled) {
169
165
  throw new Error(`๐Ÿšซ Button "${buttonText}" is not disabled as expected.`);
170
166
  }
171
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `โœ… Verified button "${buttonText}" is disabled.`);
167
+ this.log?.(`โœ… Verified button "${buttonText}" is disabled.`);
172
168
  });
@@ -8,18 +8,16 @@ Then(/^I see element "([^"]+)" exists$/, async function (selector) {
8
8
  await expect(el).toHaveCount(1);
9
9
  });
10
10
  Then("I see element exists", async function () {
11
- var _a, _b, _c;
12
11
  if (!this.element)
13
12
  throw new Error("No element stored in context");
14
- const count = (_c = (await ((_b = (_a = this.element).count) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : 1;
13
+ const count = (await this.element.count?.()) ?? 1;
15
14
  if (count === 0)
16
15
  throw new Error("Element does not exist");
17
16
  });
18
17
  Then("I see element does not exist", async function () {
19
- var _a, _b, _c;
20
18
  if (!this.element)
21
19
  throw new Error("No element stored in context");
22
- const count = (_c = (await ((_b = (_a = this.element).count) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : 1;
20
+ const count = (await this.element.count?.()) ?? 1;
23
21
  if (count > 0)
24
22
  throw new Error("Element exists but should not");
25
23
  });
@@ -70,13 +68,13 @@ Then("I see element attribute {string} contains {string}", async function (attr,
70
68
  if (!this.element)
71
69
  throw new Error("No element in context");
72
70
  const value = await this.element.getAttribute(attr);
73
- if (!(value === null || value === void 0 ? void 0 : value.includes(part))) {
71
+ if (!value?.includes(part)) {
74
72
  throw new Error(`Attribute "${attr}" does not contain "${part}". Got: "${value}"`);
75
73
  }
76
74
  });
77
75
  Then(/^I see element "([^"]+)" attribute "([^"]+)" contains "(.*)"$/, async function (selector, attribute, substring) {
78
76
  const attr = await this.page.locator(selector).getAttribute(attribute);
79
- expect(attr === null || attr === void 0 ? void 0 : attr.includes(substring)).toBeTruthy();
77
+ expect(attr?.includes(substring)).toBeTruthy();
80
78
  });
81
79
  Then(/^I see element "([^"]+)" has attribute "([^"]+)"$/, async function (selector, attribute) {
82
80
  const attr = await this.page.locator(selector).getAttribute(attribute);
@@ -2,13 +2,11 @@ import { Then } from "@cucumber/cucumber";
2
2
  import { expect } from "@playwright/test";
3
3
  // Accessing the Last Response
4
4
  Then("I should see response status {int}", function (expectedStatus) {
5
- var _a;
6
- expect((_a = this.data.lastResponse) === null || _a === void 0 ? void 0 : _a.status).toBe(expectedStatus);
5
+ expect(this.data.lastResponse?.status).toBe(expectedStatus);
7
6
  this.log(`Verified response status is ${expectedStatus}`);
8
7
  });
9
8
  Then("I should see response body contains {string}", function (expectedText) {
10
- var _a;
11
- expect((_a = this.data.lastResponse) === null || _a === void 0 ? void 0 : _a.body).toContain(expectedText);
9
+ expect(this.data.lastResponse?.body).toContain(expectedText);
12
10
  this.log(`Verified response body contains "${expectedText}"`);
13
11
  });
14
12
  Then("I see response body {string}", async function (expected) {
@@ -173,7 +171,12 @@ Then("I see response body is JSON", async function () {
173
171
  this.log(`Verified response body is valid JSON`);
174
172
  }
175
173
  catch (e) {
176
- throw new Error(`Response body is not valid JSON: ${e.message}`);
174
+ if (e instanceof Error) {
175
+ throw new Error(`Response body is not valid JSON: ${e.message}`);
176
+ }
177
+ else {
178
+ throw new Error(`Response body is not valid JSON: ${String(e)}`);
179
+ }
177
180
  }
178
181
  });
179
182
  Then("I see response body is not JSON", async function () {
@@ -186,6 +189,11 @@ Then("I see response body is not JSON", async function () {
186
189
  throw new Error(`Expected response body to not be JSON, but it is`);
187
190
  }
188
191
  catch (e) {
189
- this.log(`Verified response body is not JSON: ${e.message}`);
192
+ if (e instanceof Error) {
193
+ this.log(`Verified response body is not JSON: ${e.message}`);
194
+ }
195
+ else {
196
+ this.log(`Verified response body is not JSON: ${String(e)}`);
197
+ }
190
198
  }
191
199
  });
@@ -40,7 +40,6 @@ Then("I do not see session storage item {string}", async function (key) {
40
40
  throw new Error(`Expected sessionStorage["${key}"] to be null, but got "${value}"`);
41
41
  });
42
42
  When("I clear all saved session files", async function () {
43
- var _a, _b;
44
43
  const authDir = path.resolve("e2e/support/helper/auth");
45
44
  if (fs.existsSync(authDir)) {
46
45
  const files = fs.readdirSync(authDir);
@@ -48,12 +47,12 @@ When("I clear all saved session files", async function () {
48
47
  const filePath = path.join(authDir, file);
49
48
  if (fs.lstatSync(filePath).isFile()) {
50
49
  fs.unlinkSync(filePath);
51
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿงน Deleted session file: ${file}`);
50
+ this.log?.(`๐Ÿงน Deleted session file: ${file}`);
52
51
  }
53
52
  }
54
53
  }
55
54
  else {
56
- (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, `โš ๏ธ Auth directory not found at ${authDir}`);
55
+ this.log?.(`โš ๏ธ Auth directory not found at ${authDir}`);
57
56
  }
58
57
  });
59
58
  Then("I see session storage item {string} equals {string}", async function (key, expected) {
@@ -16,7 +16,6 @@ function getSnapshotPaths(name) {
16
16
  };
17
17
  }
18
18
  Then("I should see the page matches the snapshot {string}", async function (name) {
19
- var _a, _b;
20
19
  const { page } = this;
21
20
  const paths = getSnapshotPaths(name);
22
21
  fs.mkdirSync(BASELINE_DIR, { recursive: true });
@@ -25,7 +24,7 @@ Then("I should see the page matches the snapshot {string}", async function (name
25
24
  await page.screenshot({ path: paths.current, fullPage: true });
26
25
  if (!fs.existsSync(paths.baseline)) {
27
26
  fs.copyFileSync(paths.current, paths.baseline);
28
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿ“ธ Created baseline snapshot: ${paths.baseline}`);
27
+ this.log?.(`๐Ÿ“ธ Created baseline snapshot: ${paths.baseline}`);
29
28
  return;
30
29
  }
31
30
  const baseline = PNG.sync.read(fs.readFileSync(paths.baseline));
@@ -35,20 +34,18 @@ Then("I should see the page matches the snapshot {string}", async function (name
35
34
  const pixelDiff = pixelmatch(baseline.data, current.data, diff.data, width, height, { threshold: 0.1 });
36
35
  if (pixelDiff > 0) {
37
36
  fs.writeFileSync(paths.diff, PNG.sync.write(diff));
38
- (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, `โŒ Visual mismatch detected, diff: ${paths.diff}`);
37
+ this.log?.(`โŒ Visual mismatch detected, diff: ${paths.diff}`);
39
38
  }
40
39
  expect(pixelDiff, "Pixels that differ").toBe(0);
41
40
  });
42
41
  Then("I capture a snapshot of the element {string} as {string}", async function (selector, alias) {
43
- var _a;
44
42
  const element = this.getScope().locator(selector);
45
43
  const pathCurrent = path.join(CURRENT_DIR, `${alias}.png`);
46
44
  fs.mkdirSync(CURRENT_DIR, { recursive: true });
47
45
  await element.screenshot({ path: pathCurrent });
48
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿ“ธ Snapshot for ${selector} saved as ${alias}`);
46
+ this.log?.(`๐Ÿ“ธ Snapshot for ${selector} saved as ${alias}`);
49
47
  });
50
48
  Then("The snapshot {string} should match baseline", async function (alias) {
51
- var _a, _b;
52
49
  const paths = getSnapshotPaths(alias);
53
50
  const current = PNG.sync.read(fs.readFileSync(paths.current));
54
51
  const baseline = fs.existsSync(paths.baseline)
@@ -56,7 +53,7 @@ Then("The snapshot {string} should match baseline", async function (alias) {
56
53
  : null;
57
54
  if (!baseline) {
58
55
  fs.copyFileSync(paths.current, paths.baseline);
59
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿ“ธ Created new baseline for ${alias}`);
56
+ this.log?.(`๐Ÿ“ธ Created new baseline for ${alias}`);
60
57
  return;
61
58
  }
62
59
  const { width, height } = baseline;
@@ -64,7 +61,7 @@ Then("The snapshot {string} should match baseline", async function (alias) {
64
61
  const pixelDiff = pixelmatch(baseline.data, current.data, diff.data, width, height, { threshold: 0.1 });
65
62
  if (pixelDiff > 0) {
66
63
  fs.writeFileSync(paths.diff, PNG.sync.write(diff));
67
- (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, `โš ๏ธ Snapshot mismatch: ${alias}`);
64
+ this.log?.(`โš ๏ธ Snapshot mismatch: ${alias}`);
68
65
  }
69
66
  expect(pixelDiff).toBe(0);
70
67
  });
@@ -6,10 +6,9 @@ import { resolveValue, deriveSessionName, resolveLoginValue, } from "../helpers/
6
6
  import fs from "fs";
7
7
  import { log } from "console";
8
8
  async function tryRestoreSession(world, sessionName) {
9
- var _a;
10
9
  const storagePath = path.resolve("e2e/support/helper/auth", `${sessionName}.json`);
11
10
  if (fs.existsSync(storagePath)) {
12
- await ((_a = world.context) === null || _a === void 0 ? void 0 : _a.addCookies([]));
11
+ await world.context?.addCookies([]);
13
12
  await world.page.context().addInitScript(() => {
14
13
  // preload logic if needed
15
14
  });
@@ -91,15 +90,14 @@ When("I login as {string} user", async function (alias) {
91
90
  this.log(`๐Ÿ’พ Saved session to ${alias}User.json`);
92
91
  });
93
92
  When("I perform login with:", async function (dataTable) {
94
- var _a, _b, _c;
95
93
  const loginData = Object.fromEntries(dataTable.raw());
96
94
  const email = resolveLoginValue(loginData.email, this);
97
- const password = (_a = resolveLoginValue(loginData.password, this)) !== null && _a !== void 0 ? _a : process.env.USER_PASSWORD;
95
+ const password = resolveLoginValue(loginData.password, this) ?? process.env.USER_PASSWORD;
98
96
  if (!email)
99
97
  throw new Error("Missing or invalid email for login");
100
98
  if (!password)
101
99
  throw new Error("Missing or invalid password for login");
102
- (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, `๐Ÿ” Logging in with: ${email}`);
100
+ this.log?.(`๐Ÿ” Logging in with: ${email}`);
103
101
  await this.page.goto(`${process.env.BASE_URL}/login`);
104
102
  await this.page.waitForLoadState("networkidle");
105
103
  await this.page.fill('input[type="email"]', email);
@@ -107,10 +105,9 @@ When("I perform login with:", async function (dataTable) {
107
105
  const loginButton = this.page.getByRole("button", { name: /login/i });
108
106
  await loginButton.click();
109
107
  await this.page.waitForLoadState("networkidle");
110
- (_c = this.log) === null || _c === void 0 ? void 0 : _c.call(this, "โœ… Login successful");
108
+ this.log?.("โœ… Login successful");
111
109
  });
112
110
  async function pageLogin(world, baseUrl, email, password) {
113
- var _a;
114
111
  const { page } = world;
115
112
  await page.goto(baseUrl);
116
113
  await page.waitForLoadState("networkidle");
@@ -131,7 +128,7 @@ async function pageLogin(world, baseUrl, email, password) {
131
128
  path: path.resolve("e2e/support/helper/auth", "session.json"),
132
129
  });
133
130
  world.data["loggedIn"] = true;
134
- (_a = world.log) === null || _a === void 0 ? void 0 : _a.call(world, "โœ… Logged in and session saved.");
131
+ world.log?.("โœ… Logged in and session saved.");
135
132
  }
136
133
  else {
137
134
  console.log("Already logged in");
@@ -35,11 +35,10 @@ BeforeAll(async () => {
35
35
  console.log("๐Ÿš€ Launched shared browser for all scenarios");
36
36
  });
37
37
  AfterAll(async () => {
38
- await (sharedBrowser === null || sharedBrowser === void 0 ? void 0 : sharedBrowser.close());
38
+ await sharedBrowser?.close();
39
39
  console.log("๐Ÿงน Closed shared browser after all scenarios");
40
40
  });
41
41
  Before(async function (scenario) {
42
- var _a, _b;
43
42
  // ๐Ÿ›ก๏ธ Ensure browser is still usable
44
43
  if (!sharedBrowser || !sharedBrowser.isConnected()) {
45
44
  console.warn("โš ๏ธ Shared browser was disconnected. Restarting...");
@@ -57,7 +56,7 @@ Before(async function (scenario) {
57
56
  };
58
57
  if (fs.existsSync(SESSION_FILE)) {
59
58
  contextOptions.storageState = SESSION_FILE;
60
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, "โœ… Reusing session from saved file.");
59
+ this.log?.("โœ… Reusing session from saved file.");
61
60
  }
62
61
  const context = await sharedBrowser.newContext(contextOptions);
63
62
  const page = await context.newPage();
@@ -65,11 +64,10 @@ Before(async function (scenario) {
65
64
  this.context = context;
66
65
  this.page = page;
67
66
  if (isMobile)
68
- (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, "๐Ÿ“ฑ Mobile emulation enabled (iPhone 13 Pro)");
67
+ this.log?.("๐Ÿ“ฑ Mobile emulation enabled (iPhone 13 Pro)");
69
68
  });
70
69
  After(async function (scenario) {
71
- var _a, _b, _c;
72
- const failed = ((_a = scenario.result) === null || _a === void 0 ? void 0 : _a.status) === "FAILED";
70
+ const failed = scenario.result?.status === "FAILED";
73
71
  const name = scenario.pickle.name.replace(/[^a-z0-9]+/gi, "_").toLowerCase();
74
72
  // ๐Ÿ“ธ Screenshot on failure
75
73
  if (failed && this.page) {
@@ -86,7 +84,7 @@ After(async function (scenario) {
86
84
  // ๐ŸŽฅ Handle video recording
87
85
  let rawPath;
88
86
  try {
89
- rawPath = await ((_c = (_b = this.page) === null || _b === void 0 ? void 0 : _b.video()) === null || _c === void 0 ? void 0 : _c.path());
87
+ rawPath = await this.page?.video()?.path();
90
88
  }
91
89
  catch (err) {
92
90
  console.warn(`โš ๏ธ Unable to access video path: ${err.message}`);
@@ -17,7 +17,7 @@ export class CustomWorld extends World {
17
17
  };
18
18
  }
19
19
  async init(testInfo) {
20
- const isMobile = testInfo === null || testInfo === void 0 ? void 0 : testInfo.pickle.tags.some((tag) => tag.name === "@mobile");
20
+ const isMobile = testInfo?.pickle.tags.some((tag) => tag.name === "@mobile");
21
21
  const device = isMobile ? devices["Pixel 5"] : undefined;
22
22
  this.browser = await chromium.launch({ headless: isHeadless, slowMo });
23
23
  this.context = await this.browser.newContext({
@@ -25,34 +25,32 @@ export class CustomWorld extends World {
25
25
  recordVideo: { dir: "e2e/test-artifacts/videos" },
26
26
  });
27
27
  this.page = await this.context.newPage();
28
- this.testName = testInfo === null || testInfo === void 0 ? void 0 : testInfo.pickle.name;
28
+ this.testName = testInfo?.pickle.name;
29
29
  this.log(`๐Ÿงช Initialized context${isMobile ? " (mobile)" : ""}`);
30
30
  }
31
31
  getScope() {
32
- var _a;
33
- return (_a = this.frame) !== null && _a !== void 0 ? _a : this.page;
32
+ return this.frame ?? this.page;
34
33
  }
35
34
  exitIframe() {
36
35
  this.frame = undefined;
37
36
  this.log("โฌ…๏ธ Exited iframe, scope is now main page");
38
37
  }
39
38
  async cleanup(testInfo) {
40
- var _a, _b, _c, _d;
41
- const failed = ((_a = testInfo === null || testInfo === void 0 ? void 0 : testInfo.result) === null || _a === void 0 ? void 0 : _a.status) === "FAILED";
39
+ const failed = testInfo?.result?.status === "FAILED";
42
40
  try {
43
- await ((_b = this.page) === null || _b === void 0 ? void 0 : _b.close());
41
+ await this.page?.close();
44
42
  }
45
43
  catch (err) {
46
44
  this.log(`โš ๏ธ Error closing page: ${err.message}`);
47
45
  }
48
46
  try {
49
- await ((_c = this.context) === null || _c === void 0 ? void 0 : _c.close());
47
+ await this.context?.close();
50
48
  }
51
49
  catch (err) {
52
50
  this.log(`โš ๏ธ Error closing context: ${err.message}`);
53
51
  }
54
52
  try {
55
- await ((_d = this.browser) === null || _d === void 0 ? void 0 : _d.close());
53
+ await this.browser?.close();
56
54
  }
57
55
  catch (err) {
58
56
  this.log(`โš ๏ธ Error closing browser: ${err.message}`);
package/package.json CHANGED
@@ -1,10 +1,26 @@
1
1
  {
2
2
  "name": "playwright-cucumber-ts-steps",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "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.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./register": {
13
+ "import": "./dist/register.js"
14
+ }
15
+ },
16
+ "sideEffects": false,
17
+ "typesVersions": {
18
+ "*": {
19
+ "*": [
20
+ "dist/*"
21
+ ]
22
+ }
23
+ },
8
24
  "scripts": {
9
25
  "build": "tsc"
10
26
  },
@@ -1 +0,0 @@
1
- export {};