playwright-cucumber-ts-steps 0.1.7 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/lib/actions/clickSteps.d.ts +251 -1
- package/lib/actions/clickSteps.js +297 -47
- package/lib/actions/cookieSteps.d.ts +18 -1
- package/lib/actions/cookieSteps.js +65 -0
- package/lib/actions/debugSteps.d.ts +14 -1
- package/lib/actions/debugSteps.js +18 -3
- package/lib/actions/elementFindSteps.d.ts +668 -1
- package/lib/actions/elementFindSteps.js +808 -94
- package/lib/actions/fillFormSteps.d.ts +69 -1
- package/lib/actions/fillFormSteps.js +178 -71
- package/lib/actions/index.d.ts +11 -0
- package/lib/actions/index.js +28 -0
- package/lib/actions/inputSteps.d.ts +218 -1
- package/lib/actions/inputSteps.js +303 -57
- package/lib/actions/interceptionSteps.d.ts +169 -1
- package/lib/actions/interceptionSteps.js +258 -38
- package/lib/actions/miscSteps.d.ts +645 -1
- package/lib/actions/miscSteps.js +898 -157
- package/lib/actions/mouseSteps.d.ts +143 -1
- package/lib/actions/mouseSteps.js +200 -32
- package/lib/actions/scrollSteps.d.ts +82 -1
- package/lib/actions/scrollSteps.js +116 -16
- package/lib/actions/storageSteps.d.ts +174 -1
- package/lib/actions/storageSteps.js +253 -33
- package/lib/assertions/buttonAndTextVisibilitySteps.d.ts +245 -1
- package/lib/assertions/buttonAndTextVisibilitySteps.js +342 -91
- package/lib/assertions/cookieSteps.d.ts +75 -1
- package/lib/assertions/cookieSteps.js +97 -29
- package/lib/assertions/elementSteps.d.ts +264 -1
- package/lib/assertions/elementSteps.js +376 -78
- package/lib/assertions/formInputSteps.d.ts +248 -1
- package/lib/assertions/formInputSteps.js +342 -79
- package/lib/assertions/index.d.ts +10 -0
- package/lib/assertions/index.js +27 -0
- package/lib/assertions/interceptionRequestsSteps.d.ts +353 -1
- package/lib/assertions/interceptionRequestsSteps.js +569 -177
- package/lib/assertions/locationSteps.d.ts +217 -1
- package/lib/assertions/locationSteps.js +287 -64
- package/lib/assertions/roleTestIdSteps.d.ts +159 -1
- package/lib/assertions/roleTestIdSteps.js +217 -22
- package/lib/assertions/semanticSteps.d.ts +176 -1
- package/lib/assertions/semanticSteps.js +245 -60
- package/lib/assertions/storageSteps.d.ts +149 -1
- package/lib/assertions/storageSteps.js +201 -65
- package/lib/assertions/visualSteps.d.ts +74 -1
- package/lib/assertions/visualSteps.js +178 -45
- package/lib/custom_setups/loginHooks.js +19 -2
- package/lib/helpers/world.d.ts +3 -0
- package/lib/helpers/world.js +11 -5
- package/lib/index.d.ts +3 -21
- package/lib/index.js +3 -23
- package/package.json +9 -2
- package/src/actions/clickSteps.ts +364 -142
- package/src/actions/cookieSteps.ts +66 -0
- package/src/actions/debugSteps.ts +17 -3
- package/src/actions/elementFindSteps.ts +822 -117
- package/src/actions/fillFormSteps.ts +234 -177
- package/src/actions/index.ts +12 -0
- package/src/actions/inputSteps.ts +318 -82
- package/src/actions/interceptionSteps.ts +295 -57
- package/src/actions/miscSteps.ts +984 -254
- package/src/actions/mouseSteps.ts +212 -55
- package/src/actions/scrollSteps.ts +114 -16
- package/src/actions/storageSteps.ts +267 -42
- package/src/assertions/buttonAndTextVisibilitySteps.ts +353 -95
- package/src/assertions/cookieSteps.ts +115 -36
- package/src/assertions/elementSteps.ts +414 -85
- package/src/assertions/formInputSteps.ts +375 -108
- package/src/assertions/index.ts +11 -0
- package/src/assertions/interceptionRequestsSteps.ts +619 -195
- package/src/assertions/locationSteps.ts +280 -64
- package/src/assertions/roleTestIdSteps.ts +244 -26
- package/src/assertions/semanticSteps.ts +257 -69
- package/src/assertions/storageSteps.ts +234 -73
- package/src/assertions/visualSteps.ts +245 -68
- package/src/custom_setups/loginHooks.ts +21 -2
- package/src/helpers/world.ts +30 -4
- package/src/index.ts +4 -25
|
@@ -1,52 +1,131 @@
|
|
|
1
1
|
import { Then } from "@cucumber/cucumber";
|
|
2
|
-
import
|
|
2
|
+
import { expect } from "@playwright/test"; // Import expect for more robust assertions where applicable
|
|
3
|
+
import type { CustomWorld } from "../helpers/world"; // Assuming this path is correct
|
|
4
|
+
|
|
5
|
+
// ===================================================================================
|
|
6
|
+
// ASSERTIONS: COOKIES
|
|
7
|
+
// ===================================================================================
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
|
-
*
|
|
10
|
+
* Asserts that a cookie with the given name exists in the browser context.
|
|
11
|
+
*
|
|
12
|
+
* ```gherkin
|
|
13
|
+
* Then I see cookie {string}
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @param cookieName - The name of the cookie expected to exist.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* Then I see cookie "session_id"
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* This step retrieves all cookies from the current Playwright browser context
|
|
23
|
+
* and checks if a cookie with `cookieName` is present.
|
|
24
|
+
* @category Cookie Assertion Steps
|
|
6
25
|
*/
|
|
7
|
-
|
|
26
|
+
export async function Then_I_see_cookie(this: CustomWorld, cookieName: string) {
|
|
8
27
|
const cookies = await this.context.cookies();
|
|
9
28
|
const cookie = cookies.find((c) => c.name === cookieName);
|
|
10
|
-
|
|
11
|
-
|
|
29
|
+
|
|
30
|
+
// Using Playwright's expect for better assertion messages and retries (if configured)
|
|
31
|
+
expect(cookie, `Cookie "${cookieName}" should exist but was not found.`).toBeDefined();
|
|
32
|
+
this.log?.(`✅ Verified cookie "${cookieName}" exists.`);
|
|
33
|
+
}
|
|
34
|
+
Then("I see cookie {string}", Then_I_see_cookie);
|
|
12
35
|
|
|
13
36
|
/**
|
|
14
|
-
*
|
|
37
|
+
* Asserts that a cookie with the given name does NOT exist in the browser context.
|
|
38
|
+
*
|
|
39
|
+
* ```gherkin
|
|
40
|
+
* Then I do not see cookie {string}
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param cookieName - The name of the cookie expected NOT to exist.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* Then I do not see cookie "expired_token"
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* This step retrieves all cookies from the current Playwright browser context
|
|
50
|
+
* and asserts that no cookie with `cookieName` is present.
|
|
51
|
+
* @category Cookie Assertion Steps
|
|
15
52
|
*/
|
|
16
|
-
|
|
53
|
+
export async function Then_I_do_not_see_cookie(this: CustomWorld, cookieName: string) {
|
|
17
54
|
const cookies = await this.context.cookies();
|
|
18
|
-
const cookie = cookies.find((c) => c.name ===
|
|
19
|
-
|
|
20
|
-
|
|
55
|
+
const cookie = cookies.find((c) => c.name === cookieName);
|
|
56
|
+
|
|
57
|
+
// Using Playwright's expect for better assertion messages and retries
|
|
58
|
+
expect(cookie, `Cookie "${cookieName}" should NOT exist but was found.`).toBeUndefined();
|
|
59
|
+
this.log?.(`✅ Verified cookie "${cookieName}" does not exist.`);
|
|
60
|
+
}
|
|
61
|
+
Then("I do not see cookie {string}", Then_I_do_not_see_cookie);
|
|
21
62
|
|
|
22
63
|
/**
|
|
23
|
-
*
|
|
64
|
+
* Asserts that a cookie with the given name exists and has an exact expected value.
|
|
65
|
+
*
|
|
66
|
+
* ```gherkin
|
|
67
|
+
* Then I see cookie {string} has value {string}
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @param cookieName - The name of the cookie to check.
|
|
71
|
+
* @param expectedValue - The exact value the cookie is expected to have.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* Then I see cookie "sessionId" has value "abc123"
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* This step finds the cookie by name and then asserts that its `value` property
|
|
78
|
+
* strictly matches `expectedValue`.
|
|
79
|
+
* @category Cookie Assertion Steps
|
|
24
80
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
);
|
|
81
|
+
export async function Then_I_see_cookie_has_value(
|
|
82
|
+
this: CustomWorld,
|
|
83
|
+
cookieName: string,
|
|
84
|
+
expectedValue: string
|
|
85
|
+
) {
|
|
86
|
+
const cookies = await this.context.cookies();
|
|
87
|
+
const cookie = cookies.find((c) => c.name === cookieName);
|
|
88
|
+
|
|
89
|
+
expect(cookie, `Cookie "${cookieName}" not found.`).toBeDefined();
|
|
90
|
+
expect(
|
|
91
|
+
cookie?.value,
|
|
92
|
+
`Expected cookie "${cookieName}" to have value "${expectedValue}", but got "${cookie?.value}".`
|
|
93
|
+
).toBe(expectedValue);
|
|
94
|
+
this.log?.(`✅ Verified cookie "${cookieName}" has value "${expectedValue}".`);
|
|
95
|
+
}
|
|
96
|
+
Then("I see cookie {string} has value {string}", Then_I_see_cookie_has_value);
|
|
38
97
|
|
|
39
98
|
/**
|
|
40
|
-
*
|
|
99
|
+
* Asserts that a cookie with the given name exists and its value contains a specific substring.
|
|
100
|
+
*
|
|
101
|
+
* ```gherkin
|
|
102
|
+
* Then I see cookie {string} contains value {string}
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @param cookieName - The name of the cookie to check.
|
|
106
|
+
* @param valuePart - The substring expected to be present within the cookie's value.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* Then I see cookie "token" contains value "auth_type"
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* This step finds the cookie by name and then asserts that its `value` property
|
|
113
|
+
* includes the `valuePart` string. Useful for tokens or complex cookie values.
|
|
114
|
+
* @category Cookie Assertion Steps
|
|
41
115
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
116
|
+
export async function Then_I_see_cookie_contains_value(
|
|
117
|
+
this: CustomWorld,
|
|
118
|
+
cookieName: string,
|
|
119
|
+
valuePart: string
|
|
120
|
+
) {
|
|
121
|
+
const cookies = await this.context.cookies();
|
|
122
|
+
const cookie = cookies.find((c) => c.name === cookieName);
|
|
123
|
+
|
|
124
|
+
expect(cookie, `Cookie "${cookieName}" not found.`).toBeDefined();
|
|
125
|
+
expect(
|
|
126
|
+
cookie?.value,
|
|
127
|
+
`Expected cookie "${cookieName}" to contain "${valuePart}", but got "${cookie?.value}".`
|
|
128
|
+
).toContain(valuePart);
|
|
129
|
+
this.log?.(`✅ Verified cookie "${cookieName}" contains value "${valuePart}".`);
|
|
130
|
+
}
|
|
131
|
+
Then("I see cookie {string} contains value {string}", Then_I_see_cookie_contains_value);
|
|
@@ -1,103 +1,432 @@
|
|
|
1
1
|
import { Then } from "@cucumber/cucumber";
|
|
2
2
|
import { expect } from "@playwright/test";
|
|
3
|
-
import type { CustomWorld } from "../helpers/world";
|
|
4
|
-
//
|
|
5
|
-
// ✅ ELEMENT EXISTS
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
Then(/^I see element "([^"]+)" exists$/, async function (this: any, selector: string) {
|
|
9
|
-
const el = await this.page.locator(selector);
|
|
10
|
-
await expect(el).toHaveCount(1);
|
|
11
|
-
});
|
|
12
|
-
Then("I see element exists", async function (this: CustomWorld) {
|
|
13
|
-
if (!this.element) throw new Error("No element stored in context");
|
|
14
|
-
const count = (await this.element.count?.()) ?? 1;
|
|
15
|
-
if (count === 0) throw new Error("Element does not exist");
|
|
16
|
-
});
|
|
17
|
-
Then("I see element does not exist", async function (this: CustomWorld) {
|
|
18
|
-
if (!this.element) throw new Error("No element stored in context");
|
|
19
|
-
const count = (await this.element.count?.()) ?? 1;
|
|
20
|
-
if (count > 0) throw new Error("Element exists but should not");
|
|
21
|
-
});
|
|
22
|
-
Then("I see element is visible", async function (this: CustomWorld) {
|
|
23
|
-
if (!this.element) throw new Error("No element in context");
|
|
24
|
-
const isVisible = await this.element.isVisible();
|
|
25
|
-
if (!isVisible) throw new Error("Element is not visible");
|
|
26
|
-
});
|
|
27
|
-
Then("I see element is not visible", async function (this: CustomWorld) {
|
|
28
|
-
if (!this.element) throw new Error("No element in context");
|
|
29
|
-
const isVisible = await this.element.isVisible();
|
|
30
|
-
if (isVisible) throw new Error("Element is visible but should not be");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
Then(/^I see element "([^"]+)" does not exist$/, async function (this: any, selector: string) {
|
|
34
|
-
const el = await this.page.locator(selector);
|
|
35
|
-
await expect(el).toHaveCount(0);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
//
|
|
39
|
-
// 👁️ ELEMENT VISIBILITY
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
Then(/^I see element "([^"]+)" is visible$/, async function (this: any, selector: string) {
|
|
43
|
-
const el = this.page.locator(selector);
|
|
44
|
-
await expect(el).toBeVisible();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
Then(/^I see element "([^"]+)" is not visible$/, async function (this: any, selector: string) {
|
|
48
|
-
const el = this.page.locator(selector);
|
|
49
|
-
await expect(el).not.toBeVisible();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
// 🔎 ATTRIBUTE ASSERTIONS
|
|
54
|
-
//
|
|
3
|
+
import type { CustomWorld } from "../helpers/world"; // Assuming this path is correct
|
|
55
4
|
|
|
5
|
+
// ===================================================================================
|
|
6
|
+
// ASSERTIONS: ELEMENT EXISTENCE (IN DOM)
|
|
7
|
+
// ===================================================================================
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Asserts that at least one element matching the given selector exists in the DOM.
|
|
11
|
+
* It does not necessarily check for visibility.
|
|
12
|
+
*
|
|
13
|
+
* ```gherkin
|
|
14
|
+
* Then I see element {string} exists
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @param selector - The CSS selector of the element expected to exist.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Then I see element ".user-profile-card" exists
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* This step uses Playwright's `expect(locator).toHaveCount(1)` as a robust way to
|
|
24
|
+
* assert that exactly one matching element is present in the DOM. If multiple elements
|
|
25
|
+
* match, it will still pass as long as at least one exists (though `toHaveCount(1)`
|
|
26
|
+
* would strictly mean *only one*). For asserting multiple elements, use "Then I count X elements".
|
|
27
|
+
* @category Assertion Steps
|
|
28
|
+
*/
|
|
29
|
+
export async function Then_I_see_element_exists(this: CustomWorld, selector: string) {
|
|
30
|
+
const locator = this.page.locator(selector);
|
|
31
|
+
// Using toHaveCount(1) for "exists" implies expecting at least one, or exactly one.
|
|
32
|
+
// If the intent is *at least one*, expect(locator).first().waitFor({state: 'attached'}) is also an option.
|
|
33
|
+
// For strict "exists", toHaveCount(1) is good if you expect uniqueness.
|
|
34
|
+
await expect(locator).toHaveCount(1, { timeout: 5000 });
|
|
35
|
+
this.log?.(`✅ Verified element "${selector}" exists in the DOM.`);
|
|
36
|
+
}
|
|
37
|
+
Then(/^I see element "([^"]+)" exists$/, Then_I_see_element_exists);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Asserts that the previously stored element exists in the DOM.
|
|
41
|
+
* This checks for its presence, not necessarily its visibility.
|
|
42
|
+
*
|
|
43
|
+
* ```gherkin
|
|
44
|
+
* Then I see element exists
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* When I find element by selector ".my-dialog"
|
|
49
|
+
* Then I see element exists
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
53
|
+
* It asserts that the stored element is attached to the DOM.
|
|
54
|
+
* @category Assertion Steps
|
|
55
|
+
*/
|
|
56
|
+
export async function Then_I_see_stored_element_exists(this: CustomWorld) {
|
|
57
|
+
if (!this.element)
|
|
58
|
+
throw new Error("No element stored in context. Use a 'find' step before asserting.");
|
|
59
|
+
|
|
60
|
+
// Playwright's toBeAttached is the most robust way to check for DOM existence
|
|
61
|
+
await expect(this.element).toBeAttached({ timeout: 5000 });
|
|
62
|
+
this.log?.(`✅ Verified stored element exists in the DOM.`);
|
|
63
|
+
}
|
|
64
|
+
Then("I see element exists", Then_I_see_stored_element_exists);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Asserts that the previously stored element does NOT exist in the DOM.
|
|
68
|
+
*
|
|
69
|
+
* ```gherkin
|
|
70
|
+
* Then I see element does not exist
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* When I find element by selector "#deleted-item"
|
|
75
|
+
* Then I see element does not exist
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
79
|
+
* It asserts that the stored element is detached from the DOM.
|
|
80
|
+
* @category Assertion Steps
|
|
81
|
+
*/
|
|
82
|
+
export async function Then_I_see_stored_element_does_not_exist(this: CustomWorld) {
|
|
83
|
+
if (!this.element)
|
|
84
|
+
throw new Error("No element stored in context. Use a 'find' step before asserting.");
|
|
85
|
+
|
|
86
|
+
// Playwright's not.toBeAttached is the most robust way to check for DOM non-existence
|
|
87
|
+
await expect(this.element).not.toBeAttached({ timeout: 5000 });
|
|
88
|
+
this.log?.(`✅ Verified stored element does NOT exist in the DOM.`);
|
|
89
|
+
}
|
|
90
|
+
Then("I see element does not exist", Then_I_see_stored_element_does_not_exist);
|
|
91
|
+
|
|
92
|
+
// ===================================================================================
|
|
93
|
+
// ASSERTIONS: ELEMENT VISIBILITY (Stored Element)
|
|
94
|
+
// ===================================================================================
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Asserts that the previously stored element is visible in the viewport.
|
|
98
|
+
*
|
|
99
|
+
* ```gherkin
|
|
100
|
+
* Then I see element is visible
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* When I find element by selector ".success-message"
|
|
105
|
+
* Then I see element is visible
|
|
106
|
+
*
|
|
107
|
+
* @remarks
|
|
108
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
109
|
+
* It uses Playwright's `expect(locator).toBeVisible()` which automatically waits
|
|
110
|
+
* for the element to become visible.
|
|
111
|
+
* @category Assertion Steps
|
|
112
|
+
*/
|
|
113
|
+
export async function Then_I_see_stored_element_is_visible(this: CustomWorld) {
|
|
114
|
+
if (!this.element) throw new Error("No element stored in context to check visibility.");
|
|
115
|
+
|
|
116
|
+
await expect(this.element).toBeVisible({ timeout: 5000 });
|
|
117
|
+
this.log?.(`✅ Verified stored element is visible.`);
|
|
118
|
+
}
|
|
119
|
+
Then("I see element is visible", Then_I_see_stored_element_is_visible);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Asserts that the previously stored element is NOT visible in the viewport.
|
|
123
|
+
*
|
|
124
|
+
* ```gherkin
|
|
125
|
+
* Then I see element is not visible
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* When I find element by selector ".loading-spinner"
|
|
130
|
+
* Then I see element is not visible
|
|
131
|
+
*
|
|
132
|
+
* @remarks
|
|
133
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
134
|
+
* It uses Playwright's `expect(locator).not.toBeVisible()` which automatically waits
|
|
135
|
+
* for the element to become hidden.
|
|
136
|
+
* @category Assertion Steps
|
|
137
|
+
*/
|
|
138
|
+
export async function Then_I_see_stored_element_is_not_visible(this: CustomWorld) {
|
|
139
|
+
if (!this.element) throw new Error("No element stored in context to check non-visibility.");
|
|
140
|
+
|
|
141
|
+
await expect(this.element).not.toBeVisible({ timeout: 5000 });
|
|
142
|
+
this.log?.(`✅ Verified stored element is NOT visible.`);
|
|
143
|
+
}
|
|
144
|
+
Then("I see element is not visible", Then_I_see_stored_element_is_not_visible);
|
|
145
|
+
|
|
146
|
+
// ===================================================================================
|
|
147
|
+
// ASSERTIONS: ELEMENT EXISTENCE (Absence by Selector)
|
|
148
|
+
// ===================================================================================
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Asserts that no element matching the given selector exists in the DOM.
|
|
152
|
+
*
|
|
153
|
+
* ```gherkin
|
|
154
|
+
* Then I see element {string} does not exist
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @param selector - The CSS selector of the element expected NOT to exist.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* Then I see element ".old-feature-flag" does not exist
|
|
161
|
+
*
|
|
162
|
+
* @remarks
|
|
163
|
+
* This step uses Playwright's `expect(locator).toHaveCount(0)` as a robust way to
|
|
164
|
+
* assert that no matching elements are present in the DOM.
|
|
165
|
+
* @category Assertion Steps
|
|
166
|
+
*/
|
|
167
|
+
export async function Then_I_see_element_does_not_exist(this: CustomWorld, selector: string) {
|
|
168
|
+
const locator = this.page.locator(selector);
|
|
169
|
+
await expect(locator).toHaveCount(0, { timeout: 5000 });
|
|
170
|
+
this.log?.(`✅ Verified element "${selector}" does NOT exist in the DOM.`);
|
|
171
|
+
}
|
|
172
|
+
Then(/^I see element "([^"]+)" does not exist$/, Then_I_see_element_does_not_exist);
|
|
173
|
+
|
|
174
|
+
// ===================================================================================
|
|
175
|
+
// ASSERTIONS: ELEMENT VISIBILITY (by Selector)
|
|
176
|
+
// ===================================================================================
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Asserts that an element matching the given selector is visible in the viewport.
|
|
180
|
+
*
|
|
181
|
+
* ```gherkin
|
|
182
|
+
* Then I see element {string} is visible
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* @param selector - The CSS selector of the element expected to be visible.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* Then I see element ".main-content" is visible
|
|
189
|
+
*
|
|
190
|
+
* @remarks
|
|
191
|
+
* This step uses Playwright's `expect(locator).toBeVisible()` which automatically waits
|
|
192
|
+
* for the element to become visible.
|
|
193
|
+
* @category Assertion Steps
|
|
194
|
+
*/
|
|
195
|
+
export async function Then_I_see_element_is_visible(this: CustomWorld, selector: string) {
|
|
196
|
+
const locator = this.page.locator(selector);
|
|
197
|
+
await expect(locator).toBeVisible({ timeout: 5000 });
|
|
198
|
+
this.log?.(`✅ Verified element "${selector}" is visible.`);
|
|
199
|
+
}
|
|
200
|
+
Then(/^I see element "([^"]+)" is visible$/, Then_I_see_element_is_visible);
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Asserts that an element matching the given selector is NOT visible in the viewport.
|
|
204
|
+
*
|
|
205
|
+
* ```gherkin
|
|
206
|
+
* Then I see element {string} is not visible
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* @param selector - The CSS selector of the element expected NOT to be visible.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* Then I see element ".modal-overlay" is not visible
|
|
213
|
+
*
|
|
214
|
+
* @remarks
|
|
215
|
+
* This step uses Playwright's `expect(locator).not.toBeVisible()` which automatically waits
|
|
216
|
+
* for the element to become hidden.
|
|
217
|
+
* @category Assertion Steps
|
|
218
|
+
*/
|
|
219
|
+
export async function Then_I_see_element_is_not_visible(this: CustomWorld, selector: string) {
|
|
220
|
+
const locator = this.page.locator(selector);
|
|
221
|
+
await expect(locator).not.toBeVisible({ timeout: 5000 });
|
|
222
|
+
this.log?.(`✅ Verified element "${selector}" is NOT visible.`);
|
|
223
|
+
}
|
|
224
|
+
Then(/^I see element "([^"]+)" is not visible$/, Then_I_see_element_is_not_visible);
|
|
225
|
+
|
|
226
|
+
// ===================================================================================
|
|
227
|
+
// ASSERTIONS: ATTRIBUTE VALUES
|
|
228
|
+
// ===================================================================================
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Asserts that an element matching the given selector has a specific attribute with an exact value.
|
|
232
|
+
*
|
|
233
|
+
* ```gherkin
|
|
234
|
+
* Then I see element {string} attribute {string} equals {string}
|
|
235
|
+
* ```
|
|
236
|
+
*
|
|
237
|
+
* @param selector - The CSS selector of the element to check.
|
|
238
|
+
* @param attribute - The name of the attribute (e.g., "id", "class", "data-test").
|
|
239
|
+
* @param expectedValue - The exact expected value of the attribute.
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* Then I see element ".submit-button" attribute "disabled" equals "true"
|
|
243
|
+
*
|
|
244
|
+
* @remarks
|
|
245
|
+
* This step uses Playwright's `expect(locator).toHaveAttribute()`.
|
|
246
|
+
* @category Attribute Assertion Steps
|
|
247
|
+
*/
|
|
248
|
+
export async function Then_I_see_element_attribute_equals(
|
|
249
|
+
this: CustomWorld,
|
|
250
|
+
selector: string,
|
|
251
|
+
attribute: string,
|
|
252
|
+
expectedValue: string
|
|
253
|
+
) {
|
|
254
|
+
const locator = this.page.locator(selector);
|
|
255
|
+
await expect(locator).toHaveAttribute(attribute, expectedValue, { timeout: 5000 });
|
|
256
|
+
this.log?.(
|
|
257
|
+
`✅ Verified element "${selector}" has attribute "${attribute}" equal to "${expectedValue}".`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
56
260
|
Then(
|
|
57
261
|
/^I see element "([^"]+)" attribute "([^"]+)" equals "(.*)"$/,
|
|
58
|
-
|
|
59
|
-
const el = this.page.locator(selector);
|
|
60
|
-
await expect(el).toHaveAttribute(attribute, expected);
|
|
61
|
-
}
|
|
262
|
+
Then_I_see_element_attribute_equals
|
|
62
263
|
);
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Asserts that the previously stored element has a specific attribute with an exact value.
|
|
267
|
+
*
|
|
268
|
+
* ```gherkin
|
|
269
|
+
* Then I see element attribute {string} equals {string}
|
|
270
|
+
* ```
|
|
271
|
+
*
|
|
272
|
+
* @param attr - The name of the attribute to check.
|
|
273
|
+
* @param expectedValue - The exact expected value of the attribute.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* When I find element by selector "input[name='rememberMe']"
|
|
277
|
+
* Then I see element attribute "checked" equals "checked"
|
|
278
|
+
*
|
|
279
|
+
* @remarks
|
|
280
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
281
|
+
* It uses Playwright's `expect(locator).toHaveAttribute()`.
|
|
282
|
+
* @category Attribute Assertion Steps
|
|
283
|
+
*/
|
|
284
|
+
export async function Then_I_see_stored_element_attribute_equals(
|
|
285
|
+
this: CustomWorld,
|
|
286
|
+
attr: string,
|
|
287
|
+
expectedValue: string
|
|
288
|
+
) {
|
|
289
|
+
if (!this.element) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
"No element is currently selected. Use a 'find' step before asserting its attributes."
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
await expect(this.element).toHaveAttribute(attr, expectedValue, { timeout: 5000 });
|
|
295
|
+
this.log?.(`✅ Verified stored element has attribute "${attr}" equal to "${expectedValue}".`);
|
|
296
|
+
}
|
|
63
297
|
Then(
|
|
64
298
|
'I see element attribute "{word}" equals {string}',
|
|
65
|
-
|
|
66
|
-
if (!this.element) {
|
|
67
|
-
throw new Error("No element is currently selected. Use a 'find' step before asserting.");
|
|
68
|
-
}
|
|
69
|
-
await expect(this.element).toHaveAttribute(attr, expected);
|
|
70
|
-
}
|
|
299
|
+
Then_I_see_stored_element_attribute_equals
|
|
71
300
|
);
|
|
72
301
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
302
|
+
/**
|
|
303
|
+
* Asserts that the previously stored element has a specific attribute, regardless of its value.
|
|
304
|
+
*
|
|
305
|
+
* ```gherkin
|
|
306
|
+
* Then I see element has attribute {string}
|
|
307
|
+
* ```
|
|
308
|
+
*
|
|
309
|
+
* @param attr - The name of the attribute expected to exist.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* When I find element by selector "img.user-avatar"
|
|
313
|
+
* Then I see element has attribute "alt"
|
|
314
|
+
*
|
|
315
|
+
* @remarks
|
|
316
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
317
|
+
* It retrieves the attribute's value and asserts that it's not `null` (meaning the attribute is present).
|
|
318
|
+
* @category Attribute Assertion Steps
|
|
319
|
+
*/
|
|
320
|
+
export async function Then_I_see_stored_element_has_attribute(this: CustomWorld, attr: string) {
|
|
321
|
+
if (!this.element) throw new Error("No element stored in context to check for attribute.");
|
|
322
|
+
|
|
323
|
+
// Use Playwright's expect.toHaveAttribute for robust checking of existence (value can be empty string, but not null)
|
|
324
|
+
// For simply checking existence, we can assert that the attribute is not null or undefined.
|
|
325
|
+
const attributeValue = await this.element.getAttribute(attr, { timeout: 5000 });
|
|
326
|
+
expect(attributeValue).not.toBeNull();
|
|
327
|
+
this.log?.(`✅ Verified stored element has attribute "${attr}".`);
|
|
328
|
+
}
|
|
329
|
+
Then("I see element has attribute {string}", Then_I_see_stored_element_has_attribute);
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Asserts that the previously stored element's specific attribute contains a given substring.
|
|
333
|
+
*
|
|
334
|
+
* ```gherkin
|
|
335
|
+
* Then I see element attribute {string} contains {string}
|
|
336
|
+
* ```
|
|
337
|
+
*
|
|
338
|
+
* @param attr - The name of the attribute to check.
|
|
339
|
+
* @param part - The substring expected to be contained within the attribute's value.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* When I find element by selector ".product-image"
|
|
343
|
+
* Then I see element attribute "src" contains "thumbnail"
|
|
344
|
+
*
|
|
345
|
+
* @remarks
|
|
346
|
+
* This step requires a preceding step that sets the {@link CustomWorld.element | current element}.
|
|
347
|
+
* It retrieves the attribute's value and asserts that it includes the `part` substring.
|
|
348
|
+
* @category Attribute Assertion Steps
|
|
349
|
+
*/
|
|
350
|
+
export async function Then_I_see_stored_element_attribute_contains(
|
|
351
|
+
this: CustomWorld,
|
|
352
|
+
attr: string,
|
|
353
|
+
part: string
|
|
354
|
+
) {
|
|
355
|
+
if (!this.element) throw new Error("No element stored in context to check attribute content.");
|
|
356
|
+
|
|
357
|
+
// Use Playwright's expect.toHaveAttribute with a regex for 'contains' check
|
|
358
|
+
await expect(this.element).toHaveAttribute(attr, new RegExp(part), { timeout: 5000 });
|
|
359
|
+
this.log?.(`✅ Verified stored element attribute "${attr}" contains "${part}".`);
|
|
360
|
+
}
|
|
78
361
|
Then(
|
|
79
362
|
'I see element attribute "{word}" contains {string}',
|
|
80
|
-
|
|
81
|
-
if (!this.element) throw new Error("No element in context");
|
|
82
|
-
const value = await this.element.getAttribute(attr);
|
|
83
|
-
if (!value?.includes(part)) {
|
|
84
|
-
throw new Error(`Attribute "${attr}" does not contain "${part}". Got: "${value}"`);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
363
|
+
Then_I_see_stored_element_attribute_contains
|
|
87
364
|
);
|
|
88
365
|
|
|
366
|
+
/**
|
|
367
|
+
* Asserts that an element matching the given selector has a specific attribute containing a given substring.
|
|
368
|
+
*
|
|
369
|
+
* ```gherkin
|
|
370
|
+
* Then I see element {string} attribute {string} contains {string}
|
|
371
|
+
* ```
|
|
372
|
+
*
|
|
373
|
+
* @param selector - The CSS selector of the element to check.
|
|
374
|
+
* @param attribute - The name of the attribute.
|
|
375
|
+
* @param substring - The substring expected to be contained within the attribute's value.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* Then I see element "a.download-link" attribute "href" contains ".pdf"
|
|
379
|
+
*
|
|
380
|
+
* @remarks
|
|
381
|
+
* This step retrieves the attribute's value from the element matching the selector
|
|
382
|
+
* and asserts that it includes the `substring`.
|
|
383
|
+
* @category Attribute Assertion Steps
|
|
384
|
+
*/
|
|
385
|
+
export async function Then_I_see_element_attribute_contains(
|
|
386
|
+
this: CustomWorld,
|
|
387
|
+
selector: string,
|
|
388
|
+
attribute: string,
|
|
389
|
+
substring: string
|
|
390
|
+
) {
|
|
391
|
+
const locator = this.page.locator(selector);
|
|
392
|
+
// Use Playwright's expect.toHaveAttribute with a regex for 'contains' check
|
|
393
|
+
await expect(locator).toHaveAttribute(attribute, new RegExp(substring), { timeout: 5000 });
|
|
394
|
+
this.log?.(`✅ Verified element "${selector}" attribute "${attribute}" contains "${substring}".`);
|
|
395
|
+
}
|
|
89
396
|
Then(
|
|
90
397
|
/^I see element "([^"]+)" attribute "([^"]+)" contains "(.*)"$/,
|
|
91
|
-
|
|
92
|
-
const attr = await this.page.locator(selector).getAttribute(attribute);
|
|
93
|
-
expect(attr?.includes(substring)).toBeTruthy();
|
|
94
|
-
}
|
|
398
|
+
Then_I_see_element_attribute_contains
|
|
95
399
|
);
|
|
96
400
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
401
|
+
/**
|
|
402
|
+
* Asserts that an element matching the given selector has a specific attribute, regardless of its value.
|
|
403
|
+
*
|
|
404
|
+
* ```gherkin
|
|
405
|
+
* Then I see element {string} has attribute {string}
|
|
406
|
+
* ```
|
|
407
|
+
*
|
|
408
|
+
* @param selector - The CSS selector of the element to check.
|
|
409
|
+
* @param attribute - The name of the attribute expected to exist.
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* Then I see element "img.avatar" has attribute "src"
|
|
413
|
+
*
|
|
414
|
+
* @remarks
|
|
415
|
+
* This step retrieves the attribute's value from the element matching the selector
|
|
416
|
+
* and asserts that it's not `null` (meaning the attribute is present).
|
|
417
|
+
* @category Attribute Assertion Steps
|
|
418
|
+
*/
|
|
419
|
+
export async function Then_I_see_element_has_attribute(
|
|
420
|
+
this: CustomWorld,
|
|
421
|
+
selector: string,
|
|
422
|
+
attribute: string
|
|
423
|
+
) {
|
|
424
|
+
const locator = this.page.locator(selector);
|
|
425
|
+
// Playwright's toHaveAttribute with an empty string or regex can assert existence effectively.
|
|
426
|
+
// toHaveAttribute(attr, /.+/) ensures it exists and has *some* non-empty value.
|
|
427
|
+
// For just existence, checking if getAttribute is not null is explicit.
|
|
428
|
+
const attributeValue = await locator.getAttribute(attribute, { timeout: 5000 });
|
|
429
|
+
expect(attributeValue).not.toBeNull();
|
|
430
|
+
this.log?.(`✅ Verified element "${selector}" has attribute "${attribute}".`);
|
|
431
|
+
}
|
|
432
|
+
Then(/^I see element "([^"]+)" has attribute "([^"]+)"$/, Then_I_see_element_has_attribute);
|