@letitbexai_root/lexxit-automation-framework 0.0.0-stage → 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 +282 -3
- package/bin/lexxit-automation-framework.js +737 -0
- package/dist/actions/apiHandler.js +377 -0
- package/dist/actions/apiRequestHandler.js +447 -0
- package/dist/actions/apiRequestHandler.test.js +103 -0
- package/dist/actions/assertHandler.js +79 -0
- package/dist/actions/baseHandler.js +121 -0
- package/dist/actions/browserManager.js +508 -0
- package/dist/actions/checkboxHandler.js +186 -0
- package/dist/actions/clickHandler.js +178 -0
- package/dist/actions/customcodehandler.js +140 -0
- package/dist/actions/dropdownHandler.js +461 -0
- package/dist/actions/errors.js +84 -0
- package/dist/actions/radiobuttonHandler.js +191 -0
- package/dist/actions/textHandler.js +277 -0
- package/dist/api/healthProbes.js +139 -0
- package/dist/api/healthProbes.test.js +69 -0
- package/dist/api/server.js +425 -0
- package/dist/config.js +7 -0
- package/dist/executor/executionModeStrategy.js +29 -0
- package/dist/executor/functionMap.js +111 -0
- package/dist/executor/mapping.js +78 -0
- package/dist/executor/scriptExecutor.js +257 -0
- package/dist/executor/stepExecutor.js +159 -0
- package/dist/runner/apiPayloadConverter.js +275 -0
- package/dist/runner/testRunner.js +95 -0
- package/dist/sse/sseManager.js +114 -0
- package/dist/store/executionStore.js +197 -0
- package/dist/store/testDataStore.js +55 -0
- package/dist/types/types.js +3 -0
- package/dist/utils/healingService.js +301 -0
- package/dist/utils/locatorService.js +66 -0
- package/dist/utils/logger.js +25 -0
- package/dist/utils/metadataService.js +103 -0
- package/dist/utils/secretRedaction.js +47 -0
- package/dist/utils/secretRedaction.test.js +43 -0
- package/dist/utils/waitConditions.js +101 -0
- package/dist/validator/validator.js +124 -0
- package/package.json +51 -5
- package/public/dashboard.html +687 -0
- package/scripts/deploy/install-agent.sh +108 -0
- package/scripts/deploy/windows/disconnect-helper.ps1 +103 -0
- package/scripts/deploy/windows/install-lexxit-agent.ps1 +384 -0
- package/scripts/deploy/windows/probe-session-state.ps1 +35 -0
- package/scripts/postinstall.js +78 -0
package/README.md
CHANGED
|
@@ -1,3 +1,282 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Playwright Test Execution Framework
|
|
2
|
+
|
|
3
|
+
A Node.js + TypeScript framework that executes Playwright-based test sets defined entirely in JSON, exposed through a REST API, with a live polling dashboard to monitor execution in real time.
|
|
4
|
+
|
|
5
|
+
## Tech Stack
|
|
6
|
+
|
|
7
|
+
- Node.js 22, TypeScript
|
|
8
|
+
- Express.js (REST API)
|
|
9
|
+
- Playwright (Chromium, Firefox, Edge)
|
|
10
|
+
- In-memory execution store (no database)
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install
|
|
16
|
+
npx playwright install
|
|
17
|
+
npm run dev
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The server starts on port `5501`. On startup, the console prints the API URL and a list of available endpoints.
|
|
21
|
+
|
|
22
|
+
## Project Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
new_Framework/
|
|
26
|
+
├── src/
|
|
27
|
+
│ ├── api/
|
|
28
|
+
│ │ └── server.ts # Express server, all routes
|
|
29
|
+
│ ├── runner/
|
|
30
|
+
│ │ └── testRunner.ts # Orchestrates a full test set (sequential/parallel)
|
|
31
|
+
│ ├── executor/
|
|
32
|
+
│ │ ├── scriptExecutor.ts # Runs one test script (all its steps)
|
|
33
|
+
│ │ ├── stepExecutor.ts # Runs one step, routes to the correct handler
|
|
34
|
+
│ │ ├── mapping.ts # Parses step_script strings into function + args
|
|
35
|
+
│ │ └── functionMap.ts # Maps step_script function names to handler methods
|
|
36
|
+
│ ├── actions/
|
|
37
|
+
│ │ ├── browserManager.ts # openBrowser, closeBrowser, navigation, video
|
|
38
|
+
│ │ ├── textHandler.ts # enterText, getText, verifyText, etc.
|
|
39
|
+
│ │ ├── clickHandler.ts # click, doubleClick, rightClick, hover, etc.
|
|
40
|
+
│ │ ├── checkboxHandler.ts # check, uncheck, toggle, verifyChecked, etc.
|
|
41
|
+
│ │ ├── radiobuttonHandler.ts# select, selectByValue, selectByLabel, etc.
|
|
42
|
+
│ │ └── dropdownHandler.ts # native/combobox/multiselect dropdown actions
|
|
43
|
+
│ ├── utils/
|
|
44
|
+
│ │ ├── locatorService.ts # Resolves an element from a list of xpath locators
|
|
45
|
+
│ │ └── waitConditions.ts # waitForVisible, waitForTextChange, etc.
|
|
46
|
+
│ ├── validator/
|
|
47
|
+
│ │ └── validator.ts # Validates testset/testscript/step payload shapes
|
|
48
|
+
│ ├── store/
|
|
49
|
+
│ │ └── executionStore.ts # In-memory live execution state, keyed by execution_id
|
|
50
|
+
│ └── types/
|
|
51
|
+
│ └── types.ts # All shared TypeScript interfaces
|
|
52
|
+
├── public/
|
|
53
|
+
│ └── dashboard.html # Live polling dashboard UI
|
|
54
|
+
├── videos/ # Saved test recordings (when video_enabled)
|
|
55
|
+
├── tsconfig.json
|
|
56
|
+
└── package.json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## How a Request Flows
|
|
60
|
+
|
|
61
|
+
1. `POST /execute` receives the full test set JSON.
|
|
62
|
+
2. The payload is validated in three layers: testset, testscript, and step.
|
|
63
|
+
3. If valid, an `execution_id` (UUID) is generated and the response is returned **immediately** — the test set runs in the background.
|
|
64
|
+
4. If `open_dashboard: true`, the dashboard auto-opens in your default browser (only once per server session).
|
|
65
|
+
5. The dashboard polls the server and shows live step-by-step progress.
|
|
66
|
+
6. Once finished, the full result (same shape as a traditional synchronous response) becomes available under `final_result`.
|
|
67
|
+
|
|
68
|
+
## API Endpoints
|
|
69
|
+
|
|
70
|
+
| Method | Path | Description |
|
|
71
|
+
|--------|------|-------------|
|
|
72
|
+
| GET | `/` | Lists all available endpoints |
|
|
73
|
+
| POST | `/execute` | Submit a test set for execution |
|
|
74
|
+
| GET | `/status/:execution_id` | Live status + final result of one execution |
|
|
75
|
+
| GET | `/executions` | List all executions, latest first |
|
|
76
|
+
| GET | `/dashboard` | Live dashboard UI |
|
|
77
|
+
|
|
78
|
+
### POST /execute
|
|
79
|
+
|
|
80
|
+
Request body is the full test set JSON (see Request Format below).
|
|
81
|
+
|
|
82
|
+
Response (returned immediately, before execution finishes):
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"status": "started",
|
|
87
|
+
"execution_id": "a1b2c3d4-...",
|
|
88
|
+
"dashboard_url": "http://localhost:5501/dashboard?execution_id=a1b2c3d4-...",
|
|
89
|
+
"result_url": "http://localhost:5501/status/a1b2c3d4-..."
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If validation fails, responds with `400` and an `errors` array describing every problem found, tagged by level (`testset`, `testscript`, or `step`).
|
|
94
|
+
|
|
95
|
+
### GET /status/:execution_id
|
|
96
|
+
|
|
97
|
+
Returns the live execution state. While running, `scripts[].steps[]` update in real time (`pending` → `running` → `pass`/`fail`/`skip`). Once finished, `final_result` is populated with the complete original-style response (status, full step results, summary).
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"execution_id": "a1b2c3d4-...",
|
|
102
|
+
"test_set_name": "E2E Smoke Suite",
|
|
103
|
+
"status": "pass",
|
|
104
|
+
"start_time": "2026-06-17 10:00:00",
|
|
105
|
+
"end_time": "2026-06-17 10:00:42",
|
|
106
|
+
"scripts": [
|
|
107
|
+
{
|
|
108
|
+
"test_script_uid": "d42bbbd5-...",
|
|
109
|
+
"test_case_name": "asdfasdf444",
|
|
110
|
+
"status": "pass",
|
|
111
|
+
"steps": [
|
|
112
|
+
{
|
|
113
|
+
"step_name": "Enter 'sdf' into 'First name'",
|
|
114
|
+
"status": "pass",
|
|
115
|
+
"expected_result": "'sdf' entered into 'First name' successfully",
|
|
116
|
+
"comments": "'sdf' entered into 'First name' successfully",
|
|
117
|
+
"duration": "0 seconds"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"final_result": {
|
|
123
|
+
"status": "pass",
|
|
124
|
+
"results": [ /* ... full TestScriptResult objects ... */ ],
|
|
125
|
+
"summary": {
|
|
126
|
+
"test_set_name": "E2E Smoke Suite",
|
|
127
|
+
"total_scripts": 1,
|
|
128
|
+
"passed": 1,
|
|
129
|
+
"failed": 0,
|
|
130
|
+
"duration": "12 seconds",
|
|
131
|
+
"start_time": "2026-06-17 10:00:00",
|
|
132
|
+
"end_time": "2026-06-17 10:00:12"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Request Format
|
|
139
|
+
|
|
140
|
+
A test set request has three nested levels: testset, testscript, and step.
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"test_set_name": "E2E Smoke Suite",
|
|
145
|
+
"open_dashboard": true,
|
|
146
|
+
"parallel": false,
|
|
147
|
+
"stop_on_failure": true,
|
|
148
|
+
"video_enabled": true,
|
|
149
|
+
"exec_mode": { "mode": "medium", "delay_ms": 1000 },
|
|
150
|
+
"scripts": [
|
|
151
|
+
{
|
|
152
|
+
"test_script_uid": "d42bbbd5-f50f-4b71-a119-ef7294eab861",
|
|
153
|
+
"test_case_name": "asdfasdf444",
|
|
154
|
+
"voice_enabled": false,
|
|
155
|
+
"app_id": "1b040097-495d-4428-84d1-bd31ecc97e93",
|
|
156
|
+
"browser": "edge",
|
|
157
|
+
"headless": false,
|
|
158
|
+
"screenshot_mode": "on_failure",
|
|
159
|
+
"stop_on_failure": true,
|
|
160
|
+
"steps": [
|
|
161
|
+
{
|
|
162
|
+
"step_name": "Open edge",
|
|
163
|
+
"step_script": "tSetup.openBrowser('edge')",
|
|
164
|
+
"label": ""
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"step_name": "Navigate to URL",
|
|
168
|
+
"step_script": "tSetup.navigateToURL('https://example.com')",
|
|
169
|
+
"label": ""
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"label": "First name",
|
|
173
|
+
"locators": [
|
|
174
|
+
"//input[@id='fname']",
|
|
175
|
+
"//input[@id='fname' and @name='fname']"
|
|
176
|
+
],
|
|
177
|
+
"obj_uid": "066d39cd-b378-40c0-aa7f-e80e6c55a530",
|
|
178
|
+
"page_uid": null,
|
|
179
|
+
"step_name": "Enter 'sdf' into 'First name'",
|
|
180
|
+
"step_script": "tSetup.enterText('xpath', '//input[@id=\"fname\"]', 'sdf')",
|
|
181
|
+
"value": "sdf"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"step_name": "Close Browser",
|
|
185
|
+
"step_script": "tSetup.closeBrowser()",
|
|
186
|
+
"label": ""
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Testset-level fields
|
|
195
|
+
|
|
196
|
+
| Field | Type | Description |
|
|
197
|
+
|-------|------|--------------|
|
|
198
|
+
| `test_set_name` | string | Display name for the test set |
|
|
199
|
+
| `open_dashboard` | boolean | Auto-opens the dashboard in your browser when execution starts |
|
|
200
|
+
| `parallel` | boolean | Run scripts in parallel (max 10 concurrent) instead of sequentially |
|
|
201
|
+
| `stop_on_failure` | boolean | Reserved for testset-level stop behavior |
|
|
202
|
+
| `video_enabled` | boolean | Records a `.webm` video per script (forced `false` in `fast` exec mode) |
|
|
203
|
+
| `exec_mode` | object, optional | `{ mode: 'fast' \| 'medium' \| 'slow', delay_ms?: number }`. Defaults to `fast` if omitted |
|
|
204
|
+
| `scripts` | array | One or more test scripts |
|
|
205
|
+
|
|
206
|
+
### Testscript-level fields
|
|
207
|
+
|
|
208
|
+
| Field | Type | Description |
|
|
209
|
+
|-------|------|--------------|
|
|
210
|
+
| `test_script_uid` | string | Unique ID for this script |
|
|
211
|
+
| `test_case_name` | string | Display name |
|
|
212
|
+
| `app_id` | string | Application identifier |
|
|
213
|
+
| `browser` | `chromium` \| `firefox` \| `edge` | Browser to launch |
|
|
214
|
+
| `headless` | boolean | Run headless or headed |
|
|
215
|
+
| `screenshot_mode` | `on_failure` \| `always` \| `never` | Reserved for screenshot behavior |
|
|
216
|
+
| `stop_on_failure` | boolean | Skip remaining steps in this script once one fails |
|
|
217
|
+
| `steps` | array | Ordered list of steps to execute |
|
|
218
|
+
|
|
219
|
+
### Step-level fields
|
|
220
|
+
|
|
221
|
+
| Field | Type | Description |
|
|
222
|
+
|-------|------|--------------|
|
|
223
|
+
| `step_name` | string | Display name for the step |
|
|
224
|
+
| `step_script` | string | The action to run, e.g. `tSetup.enterText('id','fname','mahesh')` |
|
|
225
|
+
| `label` | string | Human-readable name of the target element, used in result messages |
|
|
226
|
+
| `locators` | string[] | List of xpath locators tried together (first visible match wins) |
|
|
227
|
+
| `obj_uid`, `page_uid` | string \| null | Optional metadata passed through to results |
|
|
228
|
+
|
|
229
|
+
## Execution Modes
|
|
230
|
+
|
|
231
|
+
| Mode | Behavior |
|
|
232
|
+
|------|----------|
|
|
233
|
+
| `fast` (default) | No delay between steps. `video_enabled` is forced to `false` regardless of the request value |
|
|
234
|
+
| `medium` | Waits `delay_ms` (default 1000ms if not provided) between steps. Respects `video_enabled` |
|
|
235
|
+
| `slow` | Waits `delay_ms` (default 3000ms if not provided) between steps. Respects `video_enabled` |
|
|
236
|
+
|
|
237
|
+
`delay_ms` can be passed explicitly inside `exec_mode` to override the defaults for `medium`/`slow`.
|
|
238
|
+
|
|
239
|
+
## Step Script Reference
|
|
240
|
+
|
|
241
|
+
Steps are written as `tSetup.<functionName>(args...)`. The framework parses this string and routes it to the matching handler. Currently mapped functions:
|
|
242
|
+
|
|
243
|
+
| Function | Handler |
|
|
244
|
+
|----------|---------|
|
|
245
|
+
| `openBrowser`, `closeBrowser`, `navigateToURL`, `navigateBack`, `navigateForward`, `refreshPage`, `getTitle`, `getCurrentURL` | Browser Manager |
|
|
246
|
+
| `enterText`, `typeText`, `clearText`, `getInputValue`, `appendText`, `setInputValue`, `verifyText`, `verifyValue`, `getText` | Text Handler |
|
|
247
|
+
| `clickElement`, `doubleClick`, `rightClick`, `hover` | Click Handler |
|
|
248
|
+
| `check_checkbox`, `uncheck_checkbox`, `verifyChecked`, `verifyUnchecked`, `verifyEnabled`, `verifyDisabled`, `verifyVisible`, `verifyHidden` | Checkbox Handler |
|
|
249
|
+
| `selectRadioButton` | Radiobutton Handler |
|
|
250
|
+
| `selectDropdown` | Dropdown Handler |
|
|
251
|
+
|
|
252
|
+
Functions not yet mapped (e.g. `dragAndDrop`, `file_upload`, `enterTextInFrame`, `verifyElementCount`, `verifyAttribute`, `acceptAlert`, `dismissAlert`, `getAlertText`, `verifyTitle`, `verifyURL`, `clickByJS`) are documented as comments in `functionMap.ts` for future implementation.
|
|
253
|
+
|
|
254
|
+
## Locator Resolution
|
|
255
|
+
|
|
256
|
+
Each step can provide multiple xpath locators as fallbacks. They're combined into a single OR-expression and the first visible, attached match is used. If the first locator in the list wasn't the one that matched, the step's `comments` field notes which position and xpath actually resolved — useful for cleaning up brittle locators over time.
|
|
257
|
+
|
|
258
|
+
## Live Dashboard
|
|
259
|
+
|
|
260
|
+
Visit `http://localhost:5501/dashboard` (or let it auto-open via `open_dashboard: true`).
|
|
261
|
+
|
|
262
|
+
- Left navigation lists all executions, most recent at the top.
|
|
263
|
+
- Selecting an execution shows each script and its steps.
|
|
264
|
+
- Steps show a spinner while running, then a pass/fail/skip badge.
|
|
265
|
+
- Click any step row to expand and see its expected result and comments.
|
|
266
|
+
- The dashboard polls `/executions` every 3 seconds and `/status/:execution_id` every 2 seconds — no manual refresh needed.
|
|
267
|
+
|
|
268
|
+
## Step Statuses
|
|
269
|
+
|
|
270
|
+
| Status | Meaning |
|
|
271
|
+
|--------|---------|
|
|
272
|
+
| `pending` | Not yet started (dashboard-only state) |
|
|
273
|
+
| `running` | Currently executing (dashboard-only state) |
|
|
274
|
+
| `pass` | Completed successfully |
|
|
275
|
+
| `fail` | Failed |
|
|
276
|
+
| `skip` | Skipped because an earlier step in the same script failed (when `stop_on_failure: true`) |
|
|
277
|
+
|
|
278
|
+
## Notes
|
|
279
|
+
|
|
280
|
+
- Videos are saved to the `videos/` folder, named `<test_script_uid>_<timestamp>.webm`.
|
|
281
|
+
- Parallel execution runs scripts in batches of up to 10 concurrently; batches are processed one after another.
|
|
282
|
+
- The execution store is in-memory only — restarting the server clears all execution history.
|