playwright-cucumber-ts-steps 0.0.4 โ†’ 0.0.6

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 (60) hide show
  1. package/dist/actions/Interception & Requests.d.ts +1 -0
  2. package/dist/actions/Interception & Requests.js +39 -0
  3. package/dist/actions/clickSteps.d.ts +1 -0
  4. package/dist/actions/clickSteps.js +173 -0
  5. package/dist/actions/cookieSteps.d.ts +1 -0
  6. package/dist/actions/cookieSteps.js +26 -0
  7. package/dist/actions/debugSteps.d.ts +1 -0
  8. package/dist/actions/debugSteps.js +9 -0
  9. package/dist/actions/elementFindSteps.d.ts +1 -0
  10. package/dist/actions/elementFindSteps.js +239 -0
  11. package/dist/actions/inputSteps.d.ts +1 -0
  12. package/dist/actions/inputSteps.js +166 -0
  13. package/dist/actions/interceptionSteps.d.ts +1 -0
  14. package/dist/actions/interceptionSteps.js +61 -0
  15. package/dist/actions/miscSteps.d.ts +1 -0
  16. package/dist/actions/miscSteps.js +277 -0
  17. package/dist/actions/mouseSteps.d.ts +1 -0
  18. package/dist/actions/mouseSteps.js +67 -0
  19. package/dist/actions/scrollSteps.d.ts +1 -0
  20. package/dist/actions/scrollSteps.js +21 -0
  21. package/dist/actions/storageSteps.d.ts +1 -0
  22. package/dist/actions/storageSteps.js +49 -0
  23. package/dist/assertions/InterceptionRequests.d.ts +1 -0
  24. package/dist/assertions/InterceptionRequests.js +191 -0
  25. package/dist/assertions/button_and_text_visibility.d.ts +1 -0
  26. package/dist/assertions/button_and_text_visibility.js +172 -0
  27. package/dist/assertions/cookieSteps.d.ts +1 -0
  28. package/dist/assertions/cookieSteps.js +43 -0
  29. package/dist/assertions/elementSteps.d.ts +1 -0
  30. package/dist/assertions/elementSteps.js +84 -0
  31. package/dist/assertions/formInputSteps.d.ts +1 -0
  32. package/dist/assertions/formInputSteps.js +85 -0
  33. package/dist/assertions/locationSteps.d.ts +1 -0
  34. package/dist/assertions/locationSteps.js +69 -0
  35. package/dist/assertions/roleTestIdSteps.d.ts +1 -0
  36. package/dist/assertions/roleTestIdSteps.js +24 -0
  37. package/dist/assertions/semanticSteps.d.ts +1 -0
  38. package/dist/assertions/semanticSteps.js +52 -0
  39. package/dist/assertions/storageSteps.d.ts +1 -0
  40. package/dist/assertions/storageSteps.js +70 -0
  41. package/dist/assertions/visualSteps.d.ts +1 -0
  42. package/dist/assertions/visualSteps.js +70 -0
  43. package/dist/custom_setups/global-login.d.ts +2 -0
  44. package/dist/custom_setups/global-login.js +20 -0
  45. package/dist/custom_setups/loginHooks.d.ts +1 -0
  46. package/dist/custom_setups/loginHooks.js +139 -0
  47. package/dist/helpers/compareSnapshots.d.ts +6 -0
  48. package/dist/helpers/compareSnapshots.js +14 -0
  49. package/dist/helpers/hooks.d.ts +1 -0
  50. package/dist/helpers/hooks.js +148 -0
  51. package/dist/helpers/world.js +9 -7
  52. package/dist/iframes/frames.d.ts +1 -0
  53. package/dist/iframes/frames.js +9 -0
  54. package/dist/index.d.ts +28 -5
  55. package/dist/index.js +28 -5
  56. package/dist/register.d.ts +1 -0
  57. package/dist/register.js +2 -0
  58. package/package.json +2 -8
  59. package/index.ts +0 -10
  60. package/register.ts +0 -31
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,172 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ import { expect } from "@playwright/test";
3
+ import { evaluateFaker } from "../helpers/utils/fakerUtils";
4
+ Then("I count {int} elements", async function (expectedCount) {
5
+ if (!this.elements)
6
+ throw new Error("No elements found to count");
7
+ const count = await this.elements.count();
8
+ await this.page.waitForLoadState("networkidle");
9
+ expect(count).toBe(expectedCount);
10
+ });
11
+ /**
12
+ * THEN: I see button "Submit"
13
+ */
14
+ Then(/^I see button "(.*)"$/, async function (rawText) {
15
+ let buttonText = rawText.startsWith("@")
16
+ ? this.data[rawText.slice(1)]
17
+ : rawText;
18
+ if (!buttonText) {
19
+ throw new Error(`No value found for alias: "${rawText}"`);
20
+ }
21
+ const button = this.page.getByRole("button", {
22
+ name: buttonText,
23
+ exact: false,
24
+ });
25
+ await this.page.waitForLoadState("networkidle");
26
+ await expect(button).toBeVisible();
27
+ });
28
+ /**
29
+ * THEN: I do not see button "Cancel"
30
+ */
31
+ Then(/^I do not see button "(.*)"$/, async function (rawText) {
32
+ let buttonText = rawText.startsWith("@")
33
+ ? this.data[rawText.slice(1)]
34
+ : rawText;
35
+ if (!buttonText) {
36
+ throw new Error(`No value found for alias: "${rawText}"`);
37
+ }
38
+ const button = this.page.getByRole("button", {
39
+ name: buttonText,
40
+ exact: false,
41
+ });
42
+ await this.page.waitForLoadState("networkidle");
43
+ const count = await button.count();
44
+ for (let i = 0; i < count; i++) {
45
+ const item = button.nth(i);
46
+ if (await item.isVisible()) {
47
+ throw new Error(`Button "${buttonText}" is visible but should not be`);
48
+ }
49
+ }
50
+ });
51
+ /**
52
+ * THEN: I see text "Welcome"
53
+ */
54
+ Then("I see text {string}", async function (expected) {
55
+ var _a;
56
+ const scope = this.getScope(); // โœ… Supports iframe OR main page
57
+ const locator = scope.locator(`text=${expected}`);
58
+ await locator.waitFor({ state: "visible", timeout: 5000 });
59
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `โœ… Verified text visible: ${expected}`);
60
+ });
61
+ /**
62
+ * THEN: I do not see text "Error"
63
+ */
64
+ Then("I do not see text {string}", async function (text) {
65
+ await this.page.waitForLoadState("networkidle");
66
+ const locator = this.page.locator(`:has-text("${text}")`);
67
+ const count = await locator.count();
68
+ for (let i = 0; i < count; i++) {
69
+ const item = locator.nth(i);
70
+ if (await item.isVisible()) {
71
+ throw new Error(`Text "${text}" is visible but should not be`);
72
+ }
73
+ }
74
+ });
75
+ /**
76
+ * THEN: I see visible text "Dashboard"
77
+ */
78
+ Then("I see visible text {string}", async function (text) {
79
+ await this.page.waitForLoadState("networkidle");
80
+ const locator = this.page.locator(`:text-is("${text}")`);
81
+ if (!(await locator.first().isVisible())) {
82
+ throw new Error(`Visible text "${text}" not found`);
83
+ }
84
+ });
85
+ /**
86
+ * THEN: I do not see visible text "Logout"
87
+ */
88
+ Then("I do not see visible text {string}", async function (text) {
89
+ const locator = this.page.locator(`:text-is("${text}")`);
90
+ if ((await locator.count()) > 0 && (await locator.first().isVisible())) {
91
+ throw new Error(`Visible text "${text}" should not be visible`);
92
+ }
93
+ });
94
+ Then("I see value {string}", async function (expected) {
95
+ if (!this.element)
96
+ throw new Error("No element selected");
97
+ const value = await this.element.inputValue();
98
+ if (value !== expected) {
99
+ throw new Error(`Expected value "${expected}", but got "${value}"`);
100
+ }
101
+ });
102
+ Then("I do not see value {string}", async function (unwanted) {
103
+ if (!this.element)
104
+ throw new Error("No element selected");
105
+ const value = await this.element.inputValue();
106
+ if (value === unwanted) {
107
+ throw new Error(`Value "${unwanted}" is present but should not be`);
108
+ }
109
+ });
110
+ //
111
+ // ๐Ÿ“ƒ VISIBLE TEXT ASSERTIONS
112
+ //
113
+ Then(/^I do not see text "(.*)"$/, async function (unexpectedText) {
114
+ const el = this.page.getByText(unexpectedText, { exact: true });
115
+ await expect(el).toHaveCount(0);
116
+ });
117
+ //
118
+ // ๐Ÿ†• Visible Text - Alias for clarity (optional if you want separate steps for naming)
119
+ //
120
+ Then("I see {string} in the element", async function (expected) {
121
+ var _a;
122
+ const element = this.element;
123
+ if (!element)
124
+ throw new Error("No element selected");
125
+ // โœ… Resolve alias
126
+ if (expected.startsWith("@")) {
127
+ const alias = expected.substring(1);
128
+ expected = this.data[alias];
129
+ if (!expected)
130
+ throw new Error(`No data stored for alias "@${alias}"`);
131
+ }
132
+ // โœ… Resolve faker syntax
133
+ expected = evaluateFaker(expected);
134
+ const textContent = await element.textContent();
135
+ if (!textContent)
136
+ throw new Error("Element has no text content");
137
+ expect(textContent).toContain(expected);
138
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `Verified "${expected}" in element text`);
139
+ });
140
+ Then("I see @{word} in the element", async function (alias) {
141
+ var _a;
142
+ const storedValue = this.data[alias];
143
+ if (!storedValue) {
144
+ throw new Error(`No value found in data storage under alias "@${alias}".`);
145
+ }
146
+ if (!this.element) {
147
+ throw new Error("No element found. You must get an element before asserting its contents.");
148
+ }
149
+ const actualText = ((_a = (await this.element.textContent())) === null || _a === void 0 ? void 0 : _a.trim()) || "";
150
+ expect(actualText).toContain(storedValue);
151
+ this.log(`Verified element contains value from "@${alias}" = "${storedValue}". Actual: "${actualText}"`);
152
+ });
153
+ Then("I see button {string} is disabled", async function (rawText) {
154
+ var _a;
155
+ // Resolve alias
156
+ let buttonText = rawText.startsWith("@")
157
+ ? this.data[rawText.slice(1)]
158
+ : rawText;
159
+ if (!buttonText) {
160
+ throw new Error(`No value found for alias: "${rawText}"`);
161
+ }
162
+ const button = this.page.getByRole("button", {
163
+ name: buttonText,
164
+ exact: false,
165
+ });
166
+ await expect(button).toBeVisible({ timeout: 5000 });
167
+ const isDisabled = await button.isDisabled();
168
+ if (!isDisabled) {
169
+ throw new Error(`๐Ÿšซ Button "${buttonText}" is not disabled as expected.`);
170
+ }
171
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `โœ… Verified button "${buttonText}" is disabled.`);
172
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ /**
3
+ * THEN: I see cookie "myCookie"
4
+ */
5
+ Then("I see cookie {string}", async function (cookieName) {
6
+ const cookies = await this.context.cookies();
7
+ const cookie = cookies.find((c) => c.name === cookieName);
8
+ if (!cookie)
9
+ throw new Error(`Cookie "${cookieName}" not found`);
10
+ });
11
+ /**
12
+ * THEN: I do not see cookie "myCookie"
13
+ */
14
+ Then("I do not see cookie {string}", async function (name) {
15
+ const cookies = await this.context.cookies();
16
+ const cookie = cookies.find((c) => c.name === name);
17
+ if (cookie)
18
+ throw new Error(`Cookie "${name}" was found but should not exist`);
19
+ });
20
+ /**
21
+ * THEN: I see cookie "sessionId" has value "abc123"
22
+ */
23
+ Then("I see cookie {string} has value {string}", async function (name, expectedValue) {
24
+ const cookies = await this.context.cookies();
25
+ const cookie = cookies.find((c) => c.name === name);
26
+ if (!cookie)
27
+ throw new Error(`Cookie "${name}" not found`);
28
+ if (cookie.value !== expectedValue) {
29
+ throw new Error(`Expected cookie "${name}" to have value "${expectedValue}", but got "${cookie.value}"`);
30
+ }
31
+ });
32
+ /**
33
+ * THEN: I see cookie "token" contains value "auth"
34
+ */
35
+ Then("I see cookie {string} contains value {string}", async function (name, valuePart) {
36
+ const cookies = await this.context.cookies();
37
+ const cookie = cookies.find((c) => c.name === name);
38
+ if (!cookie)
39
+ throw new Error(`Cookie "${name}" not found`);
40
+ if (!cookie.value.includes(valuePart)) {
41
+ throw new Error(`Cookie "${name}" does not contain value "${valuePart}"`);
42
+ }
43
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,84 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ import { expect } from "@playwright/test";
3
+ //
4
+ // โœ… ELEMENT EXISTS
5
+ //
6
+ Then(/^I see element "([^"]+)" exists$/, async function (selector) {
7
+ const el = await this.page.locator(selector);
8
+ await expect(el).toHaveCount(1);
9
+ });
10
+ Then("I see element exists", async function () {
11
+ var _a, _b, _c;
12
+ if (!this.element)
13
+ 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;
15
+ if (count === 0)
16
+ throw new Error("Element does not exist");
17
+ });
18
+ Then("I see element does not exist", async function () {
19
+ var _a, _b, _c;
20
+ if (!this.element)
21
+ 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;
23
+ if (count > 0)
24
+ throw new Error("Element exists but should not");
25
+ });
26
+ Then("I see element is visible", async function () {
27
+ if (!this.element)
28
+ throw new Error("No element in context");
29
+ const isVisible = await this.element.isVisible();
30
+ if (!isVisible)
31
+ throw new Error("Element is not visible");
32
+ });
33
+ Then("I see element is not visible", async function () {
34
+ if (!this.element)
35
+ throw new Error("No element in context");
36
+ const isVisible = await this.element.isVisible();
37
+ if (isVisible)
38
+ throw new Error("Element is visible but should not be");
39
+ });
40
+ Then(/^I see element "([^"]+)" does not exist$/, async function (selector) {
41
+ const el = await this.page.locator(selector);
42
+ await expect(el).toHaveCount(0);
43
+ });
44
+ //
45
+ // ๐Ÿ‘๏ธ ELEMENT VISIBILITY
46
+ //
47
+ Then(/^I see element "([^"]+)" is visible$/, async function (selector) {
48
+ const el = this.page.locator(selector);
49
+ await expect(el).toBeVisible();
50
+ });
51
+ Then(/^I see element "([^"]+)" is not visible$/, async function (selector) {
52
+ const el = this.page.locator(selector);
53
+ await expect(el).not.toBeVisible();
54
+ });
55
+ //
56
+ // ๐Ÿ”Ž ATTRIBUTE ASSERTIONS
57
+ //
58
+ Then(/^I see element "([^"]+)" attribute "([^"]+)" equals "(.*)"$/, async function (selector, attribute, expected) {
59
+ const el = this.page.locator(selector);
60
+ await expect(el).toHaveAttribute(attribute, expected);
61
+ });
62
+ Then("I see element has attribute {string}", async function (attr) {
63
+ if (!this.element)
64
+ throw new Error("No element in context");
65
+ const value = await this.element.getAttribute(attr);
66
+ if (value === null)
67
+ throw new Error(`Attribute "${attr}" not found`);
68
+ });
69
+ Then("I see element attribute {string} contains {string}", async function (attr, part) {
70
+ if (!this.element)
71
+ throw new Error("No element in context");
72
+ const value = await this.element.getAttribute(attr);
73
+ if (!(value === null || value === void 0 ? void 0 : value.includes(part))) {
74
+ throw new Error(`Attribute "${attr}" does not contain "${part}". Got: "${value}"`);
75
+ }
76
+ });
77
+ Then(/^I see element "([^"]+)" attribute "([^"]+)" contains "(.*)"$/, async function (selector, attribute, substring) {
78
+ const attr = await this.page.locator(selector).getAttribute(attribute);
79
+ expect(attr === null || attr === void 0 ? void 0 : attr.includes(substring)).toBeTruthy();
80
+ });
81
+ Then(/^I see element "([^"]+)" has attribute "([^"]+)"$/, async function (selector, attribute) {
82
+ const attr = await this.page.locator(selector).getAttribute(attribute);
83
+ expect(attr).not.toBeNull();
84
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ import { expect } from "@playwright/test";
3
+ //
4
+ // ๐Ÿงพ INPUT VALUES
5
+ //
6
+ Then(/^I see input "([^"]+)" has value "(.*)"$/, async function (selector, value) {
7
+ const el = this.page.locator(selector);
8
+ await expect(el).toHaveValue(value);
9
+ });
10
+ Then("I see input value {string}", async function (expected) {
11
+ if (!this.element)
12
+ throw new Error("No element stored in context");
13
+ const value = await this.element.inputValue();
14
+ expect(value).toBe(expected);
15
+ });
16
+ Then("I see input value contains {string}", async function (part) {
17
+ if (!this.element)
18
+ throw new Error("No element stored in context");
19
+ const value = await this.element.inputValue();
20
+ expect(value).toContain(part);
21
+ });
22
+ Then(/^I see input "([^"]+)" value contains "(.*)"$/, async function (selector, partial) {
23
+ const val = await this.page.locator(selector).inputValue();
24
+ expect(val).toContain(partial);
25
+ });
26
+ //
27
+ // ๐Ÿ“ TEXTAREA VALUES
28
+ //
29
+ Then(/^I see textarea "([^"]+)" has value "(.*)"$/, async function (selector, value) {
30
+ const el = this.page.locator(selector);
31
+ await expect(el).toHaveValue(value);
32
+ });
33
+ Then("I see textarea value {string}", async function (expected) {
34
+ if (!this.element)
35
+ throw new Error("No textarea selected");
36
+ const value = await this.element.inputValue();
37
+ if (value !== expected)
38
+ throw new Error(`Expected "${expected}", got "${value}"`);
39
+ });
40
+ Then("I see textarea value contains {string}", async function (part) {
41
+ if (!this.element)
42
+ throw new Error("No textarea selected");
43
+ const value = await this.element.inputValue();
44
+ if (!value.includes(part)) {
45
+ throw new Error(`Textarea does not contain "${part}". Got: "${value}"`);
46
+ }
47
+ });
48
+ Then(/^I see textarea "([^"]+)" value contains "(.*)"$/, async function (selector, partial) {
49
+ const val = await this.page.locator(selector).inputValue();
50
+ expect(val).toContain(partial);
51
+ });
52
+ //
53
+ // โœ… GENERIC VALUE MATCHING
54
+ //
55
+ Then(/^I see value "(.*)" in "([^"]+)"$/, async function (value, selector) {
56
+ const el = this.page.locator(selector);
57
+ await expect(el).toHaveValue(value);
58
+ });
59
+ Then(/^I do not see value "(.*)" in "([^"]+)"$/, async function (value, selector) {
60
+ const actual = await this.page.locator(selector).inputValue();
61
+ expect(actual).not.toBe(value);
62
+ });
63
+ //
64
+ // โฌ‡๏ธ OPTION IN SELECT
65
+ //
66
+ Then(/^I see option "(.*)"$/, async function (optionText) {
67
+ const el = this.page.locator(`option`, { hasText: optionText });
68
+ await expect(el).toHaveCount(1);
69
+ });
70
+ Then("I see option {string}", async function (optionText) {
71
+ const option = this.page.locator("option", { hasText: optionText });
72
+ if (!(await option.isVisible())) {
73
+ throw new Error(`Option "${optionText}" not visible`);
74
+ }
75
+ });
76
+ Then("I do not see option {string}", async function (optionText) {
77
+ const option = this.page.locator("option", { hasText: optionText });
78
+ if ((await option.count()) > 0 && (await option.first().isVisible())) {
79
+ throw new Error(`Option "${optionText}" is visible but should not be`);
80
+ }
81
+ });
82
+ Then(/^I do not see option "(.*)"$/, async function (optionText) {
83
+ const el = this.page.locator(`option`, { hasText: optionText });
84
+ await expect(el).toHaveCount(0);
85
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ import { expect } from "@playwright/test";
3
+ //
4
+ // ๐ŸŒ URL
5
+ //
6
+ Then("I see URL {string}", async function (expected) {
7
+ const url = this.page.url();
8
+ expect(url).toBe(expected);
9
+ });
10
+ Then("I do not see URL {string}", async function (notExpected) {
11
+ const url = this.page.url();
12
+ if (url === notExpected)
13
+ throw new Error(`Expected not to be on URL "${notExpected}"`);
14
+ });
15
+ Then("I see URL contains {string}", async function (expected) {
16
+ const url = this.page.url();
17
+ expect(url).toContain(expected);
18
+ });
19
+ Then("I do not see URL contains {string}", async function (notExpected) {
20
+ const url = this.page.url();
21
+ if (url.includes(notExpected)) {
22
+ throw new Error(`URL should not contain "${notExpected}", but got "${url}"`);
23
+ }
24
+ });
25
+ //
26
+ // ๐Ÿ“ LOCATION PARTS
27
+ //
28
+ Then("I see location {string}", async function (expected) {
29
+ const location = await this.page.evaluate(() => window.location.href);
30
+ if (location !== expected) {
31
+ throw new Error(`Expected location to be "${expected}", but got "${location}"`);
32
+ }
33
+ });
34
+ Then("I see pathname {string}", async function (expected) {
35
+ const pathname = await this.page.evaluate(() => window.location.pathname);
36
+ if (pathname !== expected) {
37
+ throw new Error(`Expected pathname "${expected}", but got "${pathname}"`);
38
+ }
39
+ });
40
+ Then("I see pathname contains {string}", async function (part) {
41
+ const pathname = await this.page.evaluate(() => window.location.pathname);
42
+ if (!pathname.includes(part)) {
43
+ throw new Error(`Pathname does not contain "${part}". Got: "${pathname}"`);
44
+ }
45
+ });
46
+ Then("I see hash {string}", async function (expected) {
47
+ const hash = await this.page.evaluate(() => window.location.hash);
48
+ if (hash !== expected) {
49
+ throw new Error(`Expected hash "${expected}", but got "${hash}"`);
50
+ }
51
+ });
52
+ Then("I see hash contains {string}", async function (part) {
53
+ const hash = await this.page.evaluate(() => window.location.hash);
54
+ if (!hash.includes(part)) {
55
+ throw new Error(`Expected hash to contain "${part}", but got "${hash}"`);
56
+ }
57
+ });
58
+ Then("I see search {string}", async function (expected) {
59
+ const search = await this.page.evaluate(() => window.location.search);
60
+ if (search !== expected) {
61
+ throw new Error(`Expected search to be "${expected}", but got "${search}"`);
62
+ }
63
+ });
64
+ Then("I see search contains {string}", async function (part) {
65
+ const search = await this.page.evaluate(() => window.location.search);
66
+ if (!search.includes(part)) {
67
+ throw new Error(`Search does not contain "${part}". Got: "${search}"`);
68
+ }
69
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ import { expect } from "@playwright/test";
3
+ //
4
+ // ๐Ÿงฉ ROLE-BASED ELEMENTS
5
+ //
6
+ Then(/^I see role "(.*)" with name "(.*)"$/, async function (role, name) {
7
+ const el = this.page.getByRole(role, { name, exact: true });
8
+ await expect(el).toBeVisible();
9
+ });
10
+ Then(/^I do not see role "(.*)" with name "(.*)"$/, async function (role, name) {
11
+ const el = this.page.getByRole(role, { name, exact: true });
12
+ await expect(el).toHaveCount(0);
13
+ });
14
+ //
15
+ // ๐Ÿท๏ธ TEST ID-BASED ELEMENTS
16
+ //
17
+ Then(/^I see testid "(.*)"$/, async function (testId) {
18
+ const el = this.page.getByTestId(testId);
19
+ await expect(el).toBeVisible();
20
+ });
21
+ Then(/^I do not see testid "(.*)"$/, async function (testId) {
22
+ const el = this.page.getByTestId(testId);
23
+ await expect(el).toHaveCount(0);
24
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ import { Then } from "@cucumber/cucumber";
2
+ //
3
+ // ๐Ÿง  HEADINGS
4
+ //
5
+ Then("I see heading {string}", async function (text) {
6
+ const heading = await this.page
7
+ .locator("h1, h2, h3, h4, h5, h6", { hasText: text })
8
+ .first();
9
+ if (!(await heading.isVisible())) {
10
+ throw new Error(`Heading "${text}" not found or not visible`);
11
+ }
12
+ });
13
+ Then("I do not see heading {string}", async function (text) {
14
+ const heading = this.page.locator("h1, h2, h3, h4, h5, h6", {
15
+ hasText: text,
16
+ });
17
+ if ((await heading.count()) > 0) {
18
+ const visible = await heading.first().isVisible();
19
+ if (visible)
20
+ throw new Error(`Heading "${text}" is visible but should not be`);
21
+ }
22
+ });
23
+ //
24
+ // ๐Ÿท๏ธ LABELS
25
+ //
26
+ Then("I see label {string}", async function (text) {
27
+ const label = this.page.getByLabel(text);
28
+ if (!(await label.isVisible())) {
29
+ throw new Error(`Label "${text}" not visible`);
30
+ }
31
+ });
32
+ Then("I do not see label {string}", async function (text) {
33
+ const label = this.page.getByLabel(text);
34
+ if ((await label.count()) > 0 && (await label.first().isVisible())) {
35
+ throw new Error(`Label "${text}" is visible but should not be`);
36
+ }
37
+ });
38
+ //
39
+ // ๐Ÿ”— LINKS
40
+ //
41
+ Then("I see link {string}", async function (text) {
42
+ const link = this.page.getByRole("link", { name: text });
43
+ if (!(await link.isVisible())) {
44
+ throw new Error(`Link "${text}" not visible`);
45
+ }
46
+ });
47
+ Then("I do not see link {string}", async function (text) {
48
+ const link = this.page.getByRole("link", { name: text });
49
+ if ((await link.count()) > 0 && (await link.first().isVisible())) {
50
+ throw new Error(`Link "${text}" is visible but should not be`);
51
+ }
52
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import { When, Then } from "@cucumber/cucumber";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ //
5
+ // ๐Ÿ—ƒ LOCAL STORAGE
6
+ //
7
+ Then("I see local storage item {string}", async function (key) {
8
+ const value = await this.page.evaluate((k) => localStorage.getItem(k), key);
9
+ if (value === null)
10
+ throw new Error(`Local storage item "${key}" not found`);
11
+ });
12
+ Then("I do not see local storage item {string}", async function (key) {
13
+ const value = await this.page.evaluate((k) => localStorage.getItem(k), key);
14
+ if (value !== null)
15
+ throw new Error(`Expected localStorage["${key}"] to be null, but got "${value}"`);
16
+ });
17
+ Then("I see local storage item {string} equals {string}", async function (key, expected) {
18
+ const actual = await this.page.evaluate((k) => localStorage.getItem(k), key);
19
+ if (actual !== expected) {
20
+ throw new Error(`Expected localStorage["${key}"] to be "${expected}", but got "${actual}"`);
21
+ }
22
+ });
23
+ Then("I see local storage item {string} contains {string}", async function (key, part) {
24
+ const value = await this.page.evaluate((k) => localStorage.getItem(k), key);
25
+ if (!value || !value.includes(part)) {
26
+ throw new Error(`localStorage["${key}"] does not contain "${part}". Got: "${value}"`);
27
+ }
28
+ });
29
+ //
30
+ // ๐Ÿ—‚ SESSION STORAGE
31
+ //
32
+ Then("I see session storage item {string}", async function (key) {
33
+ const value = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
34
+ if (value === null)
35
+ throw new Error(`Session storage item "${key}" not found`);
36
+ });
37
+ Then("I do not see session storage item {string}", async function (key) {
38
+ const value = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
39
+ if (value !== null)
40
+ throw new Error(`Expected sessionStorage["${key}"] to be null, but got "${value}"`);
41
+ });
42
+ When("I clear all saved session files", async function () {
43
+ var _a, _b;
44
+ const authDir = path.resolve("e2e/support/helper/auth");
45
+ if (fs.existsSync(authDir)) {
46
+ const files = fs.readdirSync(authDir);
47
+ for (const file of files) {
48
+ const filePath = path.join(authDir, file);
49
+ if (fs.lstatSync(filePath).isFile()) {
50
+ fs.unlinkSync(filePath);
51
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, `๐Ÿงน Deleted session file: ${file}`);
52
+ }
53
+ }
54
+ }
55
+ else {
56
+ (_b = this.log) === null || _b === void 0 ? void 0 : _b.call(this, `โš ๏ธ Auth directory not found at ${authDir}`);
57
+ }
58
+ });
59
+ Then("I see session storage item {string} equals {string}", async function (key, expected) {
60
+ const actual = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
61
+ if (actual !== expected) {
62
+ throw new Error(`Expected sessionStorage["${key}"] to be "${expected}", but got "${actual}"`);
63
+ }
64
+ });
65
+ Then("I see session storage item {string} contains {string}", async function (key, part) {
66
+ const value = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
67
+ if (!value || !value.includes(part)) {
68
+ throw new Error(`sessionStorage["${key}"] does not contain "${part}". Got: "${value}"`);
69
+ }
70
+ });
@@ -0,0 +1 @@
1
+ export {};