playwright-cucumber-ts-steps 1.0.1 โ†’ 1.0.3

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 (137) hide show
  1. package/README.md +270 -244
  2. package/dist/backend/actions/formTable.js +34 -0
  3. package/dist/backend/actions/index.js +5 -0
  4. package/dist/backend/actions/interactions.js +23 -0
  5. package/dist/backend/actions/navigation.js +19 -0
  6. package/dist/backend/api/assertions.js +26 -0
  7. package/dist/backend/api/index.js +5 -0
  8. package/dist/backend/api/mock.js +75 -0
  9. package/dist/backend/api/requests.js +86 -0
  10. package/dist/backend/api/state.js +15 -0
  11. package/dist/backend/assertions/expectVisible.js +8 -0
  12. package/dist/backend/assertions/index.js +5 -0
  13. package/dist/backend/assertions/pageState.js +25 -0
  14. package/dist/backend/assertions/text.js +20 -0
  15. package/dist/backend/assertions/visibility.js +20 -0
  16. package/dist/backend/auth/index.js +71 -0
  17. package/dist/backend/db/index.js +6 -0
  18. package/dist/backend/db/state.js +24 -0
  19. package/dist/backend/db/steps.js +43 -0
  20. package/dist/backend/elements/alerts.js +21 -0
  21. package/dist/backend/elements/forms.js +59 -0
  22. package/dist/backend/elements/frames.js +25 -0
  23. package/dist/backend/elements/index.js +5 -0
  24. package/dist/core/registry.js +20 -0
  25. package/dist/core/runner.js +151 -0
  26. package/dist/index.js +10 -0
  27. package/dist/reporting/index.js +43 -0
  28. package/package.json +19 -101
  29. package/LICENSE +0 -21
  30. package/lib/actions/clickSteps.d.ts +0 -251
  31. package/lib/actions/clickSteps.js +0 -415
  32. package/lib/actions/cookieSteps.d.ts +0 -18
  33. package/lib/actions/cookieSteps.js +0 -93
  34. package/lib/actions/debugSteps.d.ts +0 -14
  35. package/lib/actions/debugSteps.js +0 -23
  36. package/lib/actions/elementFindSteps.d.ts +0 -668
  37. package/lib/actions/elementFindSteps.js +0 -931
  38. package/lib/actions/fillFormSteps.d.ts +0 -69
  39. package/lib/actions/fillFormSteps.js +0 -237
  40. package/lib/actions/index.d.ts +0 -11
  41. package/lib/actions/index.js +0 -28
  42. package/lib/actions/inputSteps.d.ts +0 -218
  43. package/lib/actions/inputSteps.js +0 -343
  44. package/lib/actions/interceptionSteps.d.ts +0 -169
  45. package/lib/actions/interceptionSteps.js +0 -291
  46. package/lib/actions/miscSteps.d.ts +0 -645
  47. package/lib/actions/miscSteps.js +0 -1061
  48. package/lib/actions/mouseSteps.d.ts +0 -143
  49. package/lib/actions/mouseSteps.js +0 -234
  50. package/lib/actions/scrollSteps.d.ts +0 -82
  51. package/lib/actions/scrollSteps.js +0 -123
  52. package/lib/actions/storageSteps.d.ts +0 -174
  53. package/lib/actions/storageSteps.js +0 -292
  54. package/lib/assertions/buttonAndTextVisibilitySteps.d.ts +0 -245
  55. package/lib/assertions/buttonAndTextVisibilitySteps.js +0 -401
  56. package/lib/assertions/cookieSteps.d.ts +0 -75
  57. package/lib/assertions/cookieSteps.js +0 -113
  58. package/lib/assertions/elementSteps.d.ts +0 -264
  59. package/lib/assertions/elementSteps.js +0 -388
  60. package/lib/assertions/formInputSteps.d.ts +0 -248
  61. package/lib/assertions/formInputSteps.js +0 -350
  62. package/lib/assertions/index.d.ts +0 -10
  63. package/lib/assertions/index.js +0 -27
  64. package/lib/assertions/interceptionRequestsSteps.d.ts +0 -353
  65. package/lib/assertions/interceptionRequestsSteps.js +0 -593
  66. package/lib/assertions/locationSteps.d.ts +0 -217
  67. package/lib/assertions/locationSteps.js +0 -310
  68. package/lib/assertions/roleTestIdSteps.d.ts +0 -159
  69. package/lib/assertions/roleTestIdSteps.js +0 -221
  70. package/lib/assertions/semanticSteps.d.ts +0 -176
  71. package/lib/assertions/semanticSteps.js +0 -252
  72. package/lib/assertions/storageSteps.d.ts +0 -149
  73. package/lib/assertions/storageSteps.js +0 -210
  74. package/lib/assertions/visualSteps.d.ts +0 -74
  75. package/lib/assertions/visualSteps.js +0 -209
  76. package/lib/custom_setups/loginHooks.d.ts +0 -1
  77. package/lib/custom_setups/loginHooks.js +0 -130
  78. package/lib/helpers/checkPeerDeps.d.ts +0 -1
  79. package/lib/helpers/checkPeerDeps.js +0 -19
  80. package/lib/helpers/compareSnapshots.d.ts +0 -6
  81. package/lib/helpers/compareSnapshots.js +0 -20
  82. package/lib/helpers/hooks.d.ts +0 -1
  83. package/lib/helpers/hooks.js +0 -210
  84. package/lib/helpers/utils/fakerUtils.d.ts +0 -1
  85. package/lib/helpers/utils/fakerUtils.js +0 -60
  86. package/lib/helpers/utils/index.d.ts +0 -4
  87. package/lib/helpers/utils/index.js +0 -20
  88. package/lib/helpers/utils/optionsUtils.d.ts +0 -24
  89. package/lib/helpers/utils/optionsUtils.js +0 -88
  90. package/lib/helpers/utils/resolveUtils.d.ts +0 -6
  91. package/lib/helpers/utils/resolveUtils.js +0 -72
  92. package/lib/helpers/utils/sessionUtils.d.ts +0 -3
  93. package/lib/helpers/utils/sessionUtils.js +0 -40
  94. package/lib/helpers/world.d.ts +0 -34
  95. package/lib/helpers/world.js +0 -110
  96. package/lib/iframes/frames.d.ts +0 -1
  97. package/lib/iframes/frames.js +0 -11
  98. package/lib/index.d.ts +0 -10
  99. package/lib/index.js +0 -28
  100. package/lib/register.d.ts +0 -1
  101. package/lib/register.js +0 -6
  102. package/src/actions/clickSteps.ts +0 -429
  103. package/src/actions/cookieSteps.ts +0 -95
  104. package/src/actions/debugSteps.ts +0 -21
  105. package/src/actions/elementFindSteps.ts +0 -961
  106. package/src/actions/fillFormSteps.ts +0 -270
  107. package/src/actions/index.ts +0 -12
  108. package/src/actions/inputSteps.ts +0 -354
  109. package/src/actions/interceptionSteps.ts +0 -325
  110. package/src/actions/miscSteps.ts +0 -1144
  111. package/src/actions/mouseSteps.ts +0 -256
  112. package/src/actions/scrollSteps.ts +0 -122
  113. package/src/actions/storageSteps.ts +0 -308
  114. package/src/assertions/buttonAndTextVisibilitySteps.ts +0 -436
  115. package/src/assertions/cookieSteps.ts +0 -131
  116. package/src/assertions/elementSteps.ts +0 -432
  117. package/src/assertions/formInputSteps.ts +0 -377
  118. package/src/assertions/index.ts +0 -11
  119. package/src/assertions/interceptionRequestsSteps.ts +0 -640
  120. package/src/assertions/locationSteps.ts +0 -315
  121. package/src/assertions/roleTestIdSteps.ts +0 -254
  122. package/src/assertions/semanticSteps.ts +0 -267
  123. package/src/assertions/storageSteps.ts +0 -250
  124. package/src/assertions/visualSteps.ts +0 -275
  125. package/src/custom_setups/loginHooks.ts +0 -154
  126. package/src/helpers/checkPeerDeps.ts +0 -19
  127. package/src/helpers/compareSnapshots.ts +0 -35
  128. package/src/helpers/hooks.ts +0 -212
  129. package/src/helpers/utils/fakerUtils.ts +0 -64
  130. package/src/helpers/utils/index.ts +0 -4
  131. package/src/helpers/utils/optionsUtils.ts +0 -104
  132. package/src/helpers/utils/resolveUtils.ts +0 -74
  133. package/src/helpers/utils/sessionUtils.ts +0 -36
  134. package/src/helpers/world.ts +0 -119
  135. package/src/iframes/frames.ts +0 -15
  136. package/src/index.ts +0 -18
  137. package/src/register.ts +0 -4
package/README.md CHANGED
@@ -1,343 +1,369 @@
1
- # ๐ŸŽญ playwright-cucumber-ts-steps
1
+ # ๐ŸŽญ Playwright Cucumber TS Steps
2
2
 
3
- [![NPM](https://nodei.co/npm/playwright-cucumber-ts-steps.png?downloads=true&downloadRank=true&stars=true&height=3)](https://nodei.co/npm/playwright-cucumber-ts-steps/)
3
+ [![npm version](https://img.shields.io/npm/v/playwright-cucumber-ts-steps?style=flat-square&color=blue)](https://www.npmjs.com/package/playwright-cucumber-ts-steps)
4
+ [![Downloads](https://img.shields.io/npm/dm/playwright-cucumber-ts-steps?style=flat-square)](https://www.npmjs.com/package/playwright-cucumber-ts-steps)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
6
+ [![Playwright](https://img.shields.io/badge/tested%20with-Playwright-blueviolet?style=flat-square&logo=playwright)](https://playwright.dev)
7
+ [![TypeScript](https://img.shields.io/badge/written%20in-TypeScript-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
8
+ [![GitHub stars](https://img.shields.io/github/stars/qaPaschalE/playwright-cucumber-ts-steps)](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/stargazers)
4
9
 
5
- <table align="center" style="margin-bottom:30px;"><tr><td align="center" width="9999" heigth="9999" >
6
- <img src="https://github.com/qaPaschalE/k6-cucumber-steps/blob/main/assets/paschal%20logo%20(2).png?raw=true" alt="paschal Logo" style="margin-top:25px;" align="center"/>
7
- </td></tr></table>
10
+ **The "Low-Code" BDD Framework for Playwright.**
8
11
 
9
- [![npm](https://img.shields.io/npm/v/playwright-cucumber-ts-steps?logo=npm)](https://www.npmjs.com/package/playwright-cucumber-ts-steps)
10
- [![License](https://img.shields.io/github/license/qaPaschalE/playwright-cucumber-ts-steps?logo=github)](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/blob/main/LICENSE)
11
- [![Node.js](https://img.shields.io/badge/node-%3E=18-green?logo=node.js)](https://nodejs.org/)
12
- [![Build Status](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/actions)
13
- [![TypeScript](https://img.shields.io/badge/types-TypeScript-blue?logo=typescript)](https://www.npmjs.com/package/playwright-cucumber-ts-steps)
14
- [![Issues](https://img.shields.io/github/issues/qaPaschalE/playwright-cucumber-ts-steps?logo=github)](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/issues)
15
- [![Stars](https://img.shields.io/github/stars/qaPaschalE/playwright-cucumber-ts-steps?logo=github)](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/stargazers)
12
+ Write powerful end-to-end tests in plain English using Gherkin syntax, without managing complex glue code. `playwright-cucumber-ts-steps` provides a pre-built library of robust steps for UI, API, and Authentication testing, running natively inside Playwright.
16
13
 
17
- > A collection of reusable Playwright step definitions for Cucumber in TypeScript, designed to streamline end-to-end testing across web, API, and mobile applications.
14
+ ---
18
15
 
19
- > **Note:** This package is designed for advanced Cucumber+Playwright+TypeScript setups. For basic Playwright usage, see the [official Playwright docs](https://playwright.dev/).
16
+ ## ๐Ÿš€ Features
20
17
 
21
- ## โœจ Features
18
+ - **Zero Boilerplate:** Install and start writing `.feature` files immediately.
19
+ - **Hybrid Testing:** Mix **UI**, **API**, and **Database** steps in a single scenario.
20
+ - **Smart Auth:** Login once, save the session, and reuse it across thousands of tests.
21
+ - **Native Performance:** Runs purely on Playwright (no heavy Cucumber-JS wrapper), giving you Parallelism, Tracing, and Retries out of the box.
22
+ - **Tag Filtering:** Run specific tests like `@smoke` or `@regression` easily.
23
+ - **Auto-Reporting:** Built-in helper for HTML and Slack reports with **screenshots on failure**.
22
24
 
23
- - ๐Ÿงฉ Plug-and-play Cucumber step definitions
24
- - ๐ŸŽฏ Support for **UI**, **API**, **mobile**, **iframe**, **hybrid login**, and **visual testing**
25
- - ๐Ÿง  Smart **session management** via storageState, `localStorage`, `sessionStorage`, and alias reuse
26
- - ๐Ÿ—‚๏ธ **Alias**, **Faker**, `.env`, and dynamic JSON fixture support
27
- - ๐Ÿ“ธ **Screenshot** on failure, ๐ŸŽฅ **video recording**, and ๐Ÿ–ผ๏ธ **visual diff** with baseline comparison
28
- - ๐Ÿ“ค Supports **file upload**, **drag-and-drop**, and **multi-user session flows**
29
- - ๐ŸŒ Fully supports **API requests with inline assertions**, payload from custom folders, and session injection
30
- - โœ… Compatible with both `Page` and `FrameLocator` contexts (iframe-aware)
25
+ ---
31
26
 
32
27
  ## ๐Ÿ“ฆ Installation
33
28
 
34
29
  ```bash
35
- npm install playwright-cucumber-ts-steps
30
+ npm install playwright-cucumber-ts-steps @playwright/test
36
31
  ```
37
32
 
38
- or
39
-
40
33
  ```bash
41
- yarn add playwright-cucumber-ts-steps
34
+ npx playwright install
42
35
  ```
43
36
 
44
37
  ---
45
38
 
46
- ## ๐Ÿง  Prerequisites
39
+ ## โšก Quick Start Guide
47
40
 
48
- Ensure your project is already set up with:
41
+ ### 1. Configure Playwright
49
42
 
50
- - [`@playwright/test`](https://playwright.dev/)
51
- - [`@cucumber/cucumber`](https://github.com/cucumber/cucumber-js)
52
- - TypeScript
53
- - Cucumber IDE plugin (Optional), but Highly recommended
43
+ Update `playwright.config.ts` to use the built-in reporting helper.
54
44
 
55
- If not, run:
45
+ ```typescript
46
+ import { defineConfig } from "@playwright/test";
47
+ import { getReporters } from "playwright-cucumber-ts-steps";
56
48
 
57
- ```bash
58
- npm install --save-dev @playwright/test @cucumber/cucumber typescript ts-node
59
- npx playwright install
49
+ export default defineConfig({
50
+ testDir: "./tests",
51
+ // Sets up HTML report + Console list automatically
52
+ reporter: getReporters({ on: ["html"] }),
53
+ use: {
54
+ // We handle screenshots manually in the runner,
55
+ // but this is good as a backup
56
+ screenshot: "only-on-failure",
57
+ },
58
+ });
60
59
  ```
61
60
 
62
- ## ๐Ÿ“˜ Step Definition Documentation
61
+ ### 2. Create the Runner
63
62
 
64
- ๐Ÿ‘‰ [View Steps Documentation](https://qapaschale.github.io/playwright-cucumber-ts-steps/) and [examples](https://github.com/qaPaschale/playwright-cucumber-ts-steps/tree/master/playwright/e2e).
63
+ Create a file at `tests/bdd.spec.ts`. This is the entry point.
65
64
 
66
- ---
65
+ ```typescript
66
+ import { runTests } from "playwright-cucumber-ts-steps";
67
67
 
68
- ## ๐Ÿ› ๏ธ Usage
68
+ // Runs all feature files in the 'features' folder
69
+ runTests("features/*.feature");
70
+ ```
69
71
 
70
- 1. **Load step definitions** from the package:
72
+ ### 3. Write Your Feature
71
73
 
72
- ```ts
73
- // e2e/steps/index.ts
74
- import "playwright-cucumber-ts-steps/register";
75
- ```
74
+ Create `features/login.feature`:
76
75
 
77
- 2. **Use step definitions in your feature files**:
76
+ ```gherkin
77
+ Feature: User Authentication
78
+
79
+ @smoke
80
+ Scenario: Successful Login
81
+ Given I visit "[https://the-internet.herokuapp.com/login](https://the-internet.herokuapp.com/login)"
82
+ When I fill "#username" with "tomsmith"
83
+ And I fill "#password" with "SuperSecretPassword!"
84
+ And I click "button[type='submit']"
85
+ Then I expect "#flash" to contain text "You logged into a secure area!"
78
86
 
79
- ```gherkin
80
- Feature: Login
87
+ ```
81
88
 
82
- Scenario: User logs in
83
- Given I visit "/login"
84
- When I find input by name "Email"
85
- And I type "user@example.com"
86
- And I click button "Login"
87
- Then I see visible text "Welcome"
88
- Then I do not see URL contains "/login"
89
+ ### 4. Run Tests
89
90
 
90
- ```
91
+ ```bash
92
+ npx playwright test demo.spec.ts --headed
93
+ ```
91
94
 
92
95
  ---
93
96
 
94
- ## ๐Ÿงช Step Categories
97
+ ## ๐Ÿท๏ธ Tags & Filtering
95
98
 
96
- - โœ… **Assertions**: `I see text`, `I do not see text`, `I see button`, `I see value`, etc.
97
- - ๐ŸŽฌ **Actions**: `I click`, `I type`, `I wait`, `I switch to iframe`, etc.
98
- - ๐Ÿ“„ **Forms**: `I fill the following`, aliasing, dynamic faker values
99
- - ๐ŸŒ **API**: Request mocking, assertions, response validation
100
- - ๐Ÿ“ฑ **Mobile support**: Enable with `@mobile` tag (iPhone 13 emulation)
101
- - ๐Ÿ‘๏ธ **Visual testing**: Enable with `@visual` tag (pixelmatch diff)
99
+ You can use tags to organize your tests and run specific subsets (e.g., only Smoke tests).
102
100
 
103
- ---
101
+ **In your Feature file:**
104
102
 
105
- ## ๐Ÿงฐ Customization
103
+ ```gherkin
104
+ Feature: Checkout
106
105
 
107
- You can extend the base `CustomWorld` and define your own steps:
106
+ @smoke @critical
107
+ Scenario: Guest Checkout
108
+ ...
108
109
 
109
- ```ts
110
- // custom-world.ts
111
- import { CustomWorld as BaseWorld } from "playwright-cucumber-ts-steps";
110
+ @regression
111
+ Scenario: Registered User Checkout
112
+ ...
112
113
 
113
- export class CustomWorld extends BaseWorld {
114
- // Add your custom context or helpers here
115
- }
116
114
  ```
117
115
 
118
- ---
116
+ **In your Test Runner (`tests/bdd.spec.ts`):**
119
117
 
120
- ## ๐Ÿ” Tags & Aliases
118
+ ```typescript
119
+ import { runTests } from "playwright-cucumber-ts-steps";
121
120
 
122
- - Use aliases with `@alias` syntax:
121
+ // OPTION 1: Run Everything
122
+ // runTests('features/*.feature');
123
123
 
124
- ```gherkin
125
- Given I get element by selector "[type='text_selector']"
126
- And I store element text as "welcomeText"
127
- Then I see "@welcomeText" in the element
128
- ```
124
+ // OPTION 2: Run only Smoke tests
125
+ runTests("features/*.feature", { tags: "@smoke" });
126
+ ```
127
+
128
+ ---
129
129
 
130
- - Use faker:
130
+ ## ๐Ÿ’ก Various Usage Examples
131
131
 
132
- ```gherkin
133
- // Here below "Email" represents a faker variable "Email: () => faker.internet.email()", Continue button containing text with action click, best for Forms
132
+ ### 1. API Testing (Backend Validation)
134
133
 
135
- When I fill the following "example form page" form data:
136
- | Target | Value |
137
- | [name='email'] | Email |
138
- | Continue | Click |
139
- ```
134
+ You can validate your backend directly without opening a browser, or mix it with UI tests.
140
135
 
141
- ---
136
+ ```gherkin
137
+ Feature: User API
142
138
 
143
- ## ๐Ÿ“ธ Advanced Usage
139
+ @api
140
+ Scenario: Create and Verify User
141
+ When I make a POST request to "[https://reqres.in/api/users](https://reqres.in/api/users)" with body '{"name": "Morpheus", "job": "Leader"}'
142
+ Then I expect the response status to be 201
143
+ And I expect the response property "name" to be "Morpheus"
144
144
 
145
- These features are **optional** and can be implemented in your own `cucumber.js`:
145
+ ```
146
146
 
147
- - ๐Ÿ“ท **Visual regression testing** with pixelmatch
148
- - ๐ŸŽฅ **Video recording per scenario**
149
- - ๐Ÿ” **Session reuse** using `storageState`
147
+ ### 2. Advanced Elements (Iframes & Uploads)
150
148
 
151
- ---
149
+ Handling complex HTML elements is built-in.
152
150
 
153
- ---
151
+ ```gherkin
152
+ Feature: File Upload and Iframes
154
153
 
155
- ### โœ… Additional Supported Step Features
156
-
157
- | Feature Type | Description |
158
- | ---------------- | ------------------------------------------------------------------------------------- |
159
- | `fill form data` | Use `When I fill the following "Login" form data:` to perform actions like: |
160
- | | - `fill`, `click`, `check`, `select`, `upload:<file>` |
161
- | | - `drag:<targetSelector>` for drag-and-drop |
162
- | | - `assert:visible`, `assert:text:<value>` |
163
- | | - `request:<METHOD>:<URL>:<payload>.json` |
164
- | | - `set:localStorage:<key>`, `set:sessionStorage:<key>` |
165
- | | - `wait:<ms>`, `reload`, and use alias `@aliasName` |
166
- | Session Handling | Steps like `I login with a session data "admin.json"`, `I save session as "customer"` |
167
- | Session Restore | `I restore session cookies "customer" [with reload] [using localStorage]` |
168
- | API Assertions | Validate JSON response with `assert:json:key=expectedValue` |
154
+ Scenario: Upload Document inside Iframe
155
+ Given I visit "[https://example.com/upload](https://example.com/upload)"
156
+ # Switch context to the iframe
157
+ When I upload file "data/resume.pdf" to "#file-input" inside frame "#upload-iframe"
158
+ And I click "#submit-btn" inside frame "#upload-iframe"
159
+ Then I expect "div.success" inside frame "#upload-iframe" to be visible
169
160
 
170
- ---
161
+ ```
162
+
163
+ ### 3. The "Login Once" Pattern (Authentication)
171
164
 
172
- ### โœ… Extended Usage Examples
165
+ Speed up your suite by 10x. Login once, save the cookies, and reuse them.
166
+
167
+ **Step 1: Create a Setup Feature (`features/setup.feature`)**
173
168
 
174
169
  ```gherkin
175
- Scenario: Login and save session
176
- When I fill the following "Login" form data:
177
- | input[name='email'] | test@example.com |
178
- | input[name='password'] | @userPassword |
179
- | input[type='checkbox'] | check |
180
- | button:has-text("Sign In") | click |
181
- | .welcome | assert:visible |
182
- | .role | assert:text:Admin |
183
- And I save session as "admin"
184
-
185
- Scenario: Restore user session
186
- Given I restore session cookies "admin" with reload using localStorage
187
- When I visit "/dashboard"
188
- Then I see text "Welcome back"
189
-
190
- Scenario: API login + inject session
191
- When I fill the following "Login" form data:
192
- | request:POST:/api/login:adminPayload.json | saveAs:loginData |
193
- | set:localStorage:token | @loginData.token |
194
- | save session as | adminViaAPI |
170
+ Feature: Setup
171
+
172
+ @setup
173
+ Scenario: Admin Login
174
+ Given I visit "/login"
175
+ When I fill "#user" with "admin"
176
+ And I fill "#pass" with "1234"
177
+ And I click "#login-btn"
178
+ And I expect "#dashboard" to be visible
179
+ # Saves session to ./auth/admin.json
180
+ And I save the browser state to "admin.json"
181
+
195
182
  ```
196
183
 
197
- ---
184
+ **Step 2: Use in Daily Tests (`features/admin.feature`)**
185
+
186
+ ```gherkin
187
+ Feature: Admin Panel
188
+
189
+ Scenario: Check Reports
190
+ # Loads cookies instantly - No login UI needed!
191
+ Given I load the browser state from "admin.json"
192
+ When I visit "/admin/reports"
193
+ Then I expect "h1" to have text "Weekly Reports"
198
194
 
199
- ### โœ… Folder Structure Suggestion
200
-
201
- ```text
202
- e2e/
203
- โ”œโ”€โ”€ features/ # .feature files
204
- โ”œโ”€โ”€ step_definitions/
205
- โ”‚ โ””โ”€โ”€ index.ts # import from this package
206
- โ”œโ”€โ”€ support/
207
- โ”‚ โ”œโ”€โ”€ world.ts # CustomWorld extends with iframe support
208
- โ”‚ โ”œโ”€โ”€ hooks.ts # artifact & session manager
209
- โ”‚ โ””โ”€โ”€ helpers/
210
- โ”‚ โ””โ”€โ”€ resolveUtils.ts # alias/env/json resolver
211
- โ”œโ”€โ”€ test-data/ # JSON fixtures
212
- โ”œโ”€โ”€ payload/ # API request payloads
213
195
  ```
214
196
 
215
- ---
197
+ ### 4. Data Tables (Forms)
216
198
 
217
- Hereโ€™s a full `cucumber.js` config file that includes **all the configurable options** integrated so far. This supports:
199
+ Fill out entire forms in a single step using a Data Table. You can type, click, check, or assert visibility in one go.
218
200
 
219
- - โœ… CLI/env override for artifact directories
220
- - โœ… Visual testing toggle
221
- - โœ… Screenshot and video toggle
222
- - โœ… Device emulation via `MOBILE_DEVICE` env or world param
223
- - โœ… Multiple profiles (`default`, `mobile`, `visual`, `ci`)
224
- - โœ… Parallel test execution and ts-node for TypeScript support
201
+ ```gherkin
202
+ Scenario: Registration
203
+ When I fill the following "Registration" form data:
204
+ | #first-name | John |
205
+ | #last-name | Doe |
206
+ | #email | john@test.com |
207
+ | #newsletter | check |
208
+ | #submit-btn | click |
209
+ | .success | assert:visible |
210
+ ```
225
211
 
226
- ---
212
+ ### 5. API Testing (Tables & Files)
227
213
 
228
- ### โœ… `cucumber.js`
214
+ Validate your backend directly. You can send payloads via Tables or JSON Files.
229
215
 
230
- ```js
231
- import path from "path";
232
- import dotenv from "dotenv";
216
+ #### Option A: Data Table Payload
233
217
 
234
- dotenv.config();
218
+ ```gherkin
219
+ Scenario: Create User (Table)
220
+ When I make a POST request to "[https://reqres.in/api/users](https://reqres.in/api/users)" with data:
221
+ | name | Neo |
222
+ | job | The Chosen |
223
+ Then I expect the response status to be 201
224
+ And I expect the response property "name" to be "Neo"
225
+ ```
235
226
 
236
- const ARTIFACT_DIR = process.env.TEST_ARTIFACT_DIR || "test-artifacts";
227
+ #### Option B: File Payload
237
228
 
238
- const defaultWorldParams = {
239
- artifactDir: ARTIFACT_DIR,
240
- payloadDir: "payloads",
241
- enableTrace: process.env.ENABLE_TRACE || "fail", // "false" | "fail" | "all"
242
- enableScreenshots: process.env.ENABLE_SCREENSHOTS || "fail", // "false" | "fail" | "all"
243
- enableVideos: process.env.ENABLE_VIDEOS || "all", // "false" | "fail" | "all"
244
- enableVisualTest: process.env.ENABLE_VISUAL_TEST === "true",
245
- device: process.env.MOBILE_DEVICE || undefined, // e.g., "Pixel 5"
246
- };
229
+ ```gherkin
230
+ Scenario: Create User (File)
231
+ # Reads from 'data/user.json' in your project root
232
+ When I make a POST request to "/api/users" with payload from "data/user.json"
233
+ Then I expect the response status to be 201
234
+ ```
247
235
 
248
- export default {
249
- default: {
250
- require: ["ts-node/register", "src/test/steps/**/*.ts", "src/test/support/**/*.ts"],
251
- format: ["progress", `html:${path.join(ARTIFACT_DIR, "report.html")}`],
252
- publishQuiet: true,
253
- paths: ["src/test/features/**/*.feature"],
254
- parallel: 2,
255
- worldParameters: defaultWorldParams,
256
- },
236
+ ### 6. Network Mocking
257
237
 
258
- mobile: {
259
- require: ["ts-node/register", "src/test/steps/**/*.ts", "src/test/support/**/*.ts"],
260
- format: ["progress"],
261
- publishQuiet: true,
262
- paths: ["src/test/features/**/*.feature"],
263
- parallel: 1,
264
- tags: "@mobile",
265
- worldParameters: {
266
- ...defaultWorldParams,
267
- device: process.env.MOBILE_DEVICE || "iPhone 13 Pro",
268
- },
269
- },
238
+ Simulate backend responses to test UI behavior without relying on real APIs.
270
239
 
271
- visual: {
272
- require: ["ts-node/register", "src/test/steps/**/*.ts", "src/test/support/**/*.ts"],
273
- format: ["progress"],
274
- publishQuiet: true,
275
- paths: ["src/test/features/**/*.feature"],
276
- tags: "@visual",
277
- worldParameters: {
278
- ...defaultWorldParams,
279
- enableVisualTest: true,
280
- },
281
- },
240
+ ```gherkin
241
+ Scenario: Mocking User Profile
242
+ # Intercept calls to /api/user/1 and return fake data
243
+ Given I mock the API endpoint "*/**/api/user/1" with body '{"name": "Mocked User"}'
244
+
245
+ # When the UI calls the API, it gets our fake data
246
+ When I visit "/profile"
247
+ Then I expect "#username-display" to have text "Mocked User"
282
248
 
283
- ci: {
284
- require: ["ts-node/register", "src/test/steps/**/*.ts", "src/test/support/**/*.ts"],
285
- format: ["progress", `json:${path.join(ARTIFACT_DIR, "report.json")}`],
286
- publishQuiet: true,
287
- paths: ["src/test/features/**/*.feature"],
288
- parallel: 4,
289
- worldParameters: {
290
- ...defaultWorldParams,
291
- enableScreenshots: true,
292
- enableVideos: true,
293
- enableVisualTest: false,
294
- },
295
- },
296
- };
297
249
  ```
298
250
 
299
- ---
251
+ ### 7. Database Testing (Adapter Pattern)
300
252
 
301
- ### โœ… Usage Examples
253
+ You can validate database states by injecting your own DB driver into the runner.
302
254
 
303
- ```bash
304
- # Run default suite
305
- npx cucumber-js --config cucumber.js
255
+ **1. In your `bdd.spec.ts`:**
256
+
257
+ ```typescript
258
+ import { runTests } from "playwright-cucumber-ts-steps";
259
+ import pg from "pg"; // Your driver (pg, mysql, mongo, etc)
306
260
 
307
- # Run mobile tests with device from env
308
- MOBILE_DEVICE="Pixel 5" npx cucumber-js --config cucumber.js --profile mobile
261
+ // wrapper function
262
+ const queryDb = async (query: string) => {
263
+ const client = new pg.Client(process.env.DB_URL);
264
+ await client.connect();
265
+ const res = await client.query(query);
266
+ await client.end();
267
+ return res.rows; // Must return an array of objects
268
+ };
269
+
270
+ runTests("features/*.feature", { dbQuery: queryDb });
271
+ ```
309
272
 
310
- # Run visual regression tests
311
- ENABLE_VISUAL_TEST=true npx cucumber-js --config cucumber.js --profile visual
273
+ **2. In your `Feature file`:**
312
274
 
313
- # Run in CI profile with JSON output
314
- npx cucumber-js --config cucumber.js --profile ci
275
+ ```gherkin
276
+ Scenario: Create User
277
+ When I run the database query "INSERT INTO users (name) VALUES ('Bob')"
278
+ Then I expect the database to return 1 record
279
+ And I expect the first database record to contain:
280
+ | name | Bob |
315
281
  ```
316
282
 
317
283
  ---
318
284
 
319
- ### โœ… Summary of Supported Options
285
+ ## ๐Ÿ“– Step Glossary (Cheat Sheet)
286
+
287
+ ### ๐Ÿ–ฑ๏ธ Actions
288
+
289
+ | Step | Usage Example |
290
+ | ---------------- | -------------------------------------- |
291
+ | **Visit** | `I visit "https://google.com"` |
292
+ | **Click** | `I click "#submit-btn"` |
293
+ | **Force Click** | `I force click "#hidden-btn"` |
294
+ | **Double Click** | `I double click ".icon"` |
295
+ | **Fill Input** | `I fill "#email" with "user@test.com"` |
296
+ | **Press Key** | `I press "Enter"` (or "Tab", "Escape") |
297
+ | **Wait** | `I wait for 2000 milliseconds` |
298
+ | **Reload** | `I reload the page` |
299
+ | **Go Back** | `I go back` |
300
+
301
+ ### โœ… Assertions
302
+
303
+ | Step | Usage Example |
304
+ | ---------------- | -------------------------------------------------------------- |
305
+ | **Visibility** | `I expect "#modal" to be visible` |
306
+ | **Hidden** | `I expect "#loader" to be hidden` |
307
+ | **Exact Text** | `I expect "#header" to have text "Welcome"` |
308
+ | **Partial Text** | `I expect ".error" to contain text "Failed"` |
309
+ | **Input Value** | `I expect "#username" to have value "admin"` |
310
+ | **Exact URL** | `I expect the url to be "https://site.com/home"` |
311
+ | **Partial URL** | `I expect the url to contain "/dashboard"` |
312
+ | **Title** | `I expect the title to contain "Home Page"` |
313
+ | **Attribute** | `I expect "img" to have attribute "src" with value "logo.png"` |
314
+ | **Screenshot** | `I expect the page screenshot to match "home.png"` |
315
+
316
+ ### ๐Ÿงฉ Forms & Elements
317
+
318
+ | Step | Usage Example |
319
+ | --------------------- | ---------------------------------------------- |
320
+ | **Select (Dropdown)** | `I select option "Canada" from "#country"` |
321
+ | **Check Box** | `I check "#terms-checkbox"` |
322
+ | **Uncheck** | `I uncheck "#newsletter"` |
323
+ | **Upload File** | `I upload file "data.csv" to "#upload"` |
324
+ | **Handle Alert** | `I accept the next dialog` |
325
+ | **Frame Click** | `I click "#btn" inside frame "#payment-frame"` |
326
+
327
+ ### ๐ŸŒ API
328
+
329
+ | Step | Usage Example |
330
+ | ---------------- | ------------------------------------------------------------- |
331
+ | **GET** | `I make a GET request to "/api/users"` |
332
+ | **DELETE** | `I make a DELETE request to "/api/users/1"` |
333
+ | **POST** | `I make a POST request to "/api/login" with body '{"u":"1"}'` |
334
+ | **Status Check** | `I expect the response status to be 200` |
335
+ | **JSON Check** | `I expect the response property "data.id" to be "99"` |
320
336
 
321
- | Setting | CLI/Env Variable | `worldParameters` Key | Purpose |
322
- | ------------------ | -------------------- | --------------------- | ------------------------------------------- |
323
- | Screenshot toggle | `ENABLE_SCREENSHOTS` | `enableScreenshots` | Capture screenshots on failure |
324
- | Video toggle | `ENABLE_VIDEOS` | `enableVideos` | Enable/disable video recording |
325
- | Visual testing | `ENABLE_VISUAL_TEST` | `enableVisualTest` | Capture and compare visual snapshots |
326
- | Artifact directory | `TEST_ARTIFACT_DIR` | `artifactDir` | Where to save screenshots, videos, etc. |
327
- | Mobile device emu | `MOBILE_DEVICE` | `device` | Device name for Playwright mobile emulation |
337
+ ---
328
338
 
329
- ## ๐Ÿงพ License
339
+ ## ๐Ÿ› ๏ธ Extending (Custom Steps)
330
340
 
331
- [MIT](LICENSE)
341
+ Need a step that isn't included? You can easily register your own in your spec file.
332
342
 
333
- ---
343
+ ```typescript
344
+ // tests/bdd.spec.ts
345
+ import { runTests, Step } from "playwright-cucumber-ts-steps";
346
+
347
+ // 1. Define custom step
348
+ Step("I scroll to the bottom of the page", async (page) => {
349
+ await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
350
+ });
351
+
352
+ // 2. Run tests
353
+ runTests("features/*.feature");
354
+ ```
355
+
356
+ Then use it in your feature:
334
357
 
335
- ## ๐Ÿ™‹โ€โ™‚๏ธ Contributing
358
+ ```gherkin
359
+ Scenario: Scroll Test
360
+ Given I visit "[https://infinite-scroll.com](https://infinite-scroll.com)"
361
+ When I scroll to the bottom of the page
336
362
 
337
- Contributions, improvements, and suggestions are welcome! Feel free to open an issue or pull request.
363
+ ```
338
364
 
339
365
  ---
340
366
 
341
- ## ๐Ÿ’ฌ Questions?
367
+ ## ๐Ÿ“„ License
342
368
 
343
- Open an issue on [GitHub Issues](https://github.com/qaPaschalE/playwright-cucumber-ts-steps/issues) or reach out via discussions.
369
+ MIT ยฉ 2024
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const registry_1 = require("../../core/registry");
4
+ const test_1 = require("@playwright/test");
5
+ // CHANGE: Removed the ':' at the end of the string below
6
+ (0, registry_1.Step)("I fill the following {string} form data", async (page, formName, tableData) => {
7
+ console.log(`๐Ÿ“ Processing Form: ${formName}`);
8
+ // The runner passes the table data as the last argument
9
+ // tableData = [ ['#username', 'tomsmith'], ['#password', '...'] ]
10
+ // Guard clause: Ensure tableData exists to prevent crashes if user forgets the table
11
+ if (!tableData || !Array.isArray(tableData)) {
12
+ throw new Error(`โŒ The step "I fill the following '${formName}' form data" requires a Data Table below it.`);
13
+ }
14
+ for (const row of tableData) {
15
+ const selector = row[0];
16
+ const value = row[1];
17
+ if (value === "click") {
18
+ await page.click(selector);
19
+ }
20
+ else if (value === "check") {
21
+ await page.check(selector);
22
+ }
23
+ else if (value === "assert:visible") {
24
+ await (0, test_1.expect)(page.locator(selector)).toBeVisible();
25
+ }
26
+ else if (value.startsWith("assert:text:")) {
27
+ const text = value.replace("assert:text:", "");
28
+ await (0, test_1.expect)(page.locator(selector)).toHaveText(text);
29
+ }
30
+ else {
31
+ await page.fill(selector, value);
32
+ }
33
+ }
34
+ });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./navigation");
4
+ require("./interactions");
5
+ require("./formTable");