testblocks 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +333 -0
- package/dist/cli/executor.d.ts +32 -0
- package/dist/cli/executor.js +517 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +411 -0
- package/dist/cli/reporters.d.ts +62 -0
- package/dist/cli/reporters.js +451 -0
- package/dist/client/assets/index-4hbFPUhP.js +2087 -0
- package/dist/client/assets/index-4hbFPUhP.js.map +1 -0
- package/dist/client/assets/index-Dnk1ti7l.css +1 -0
- package/dist/client/index.html +25 -0
- package/dist/core/blocks/api.d.ts +2 -0
- package/dist/core/blocks/api.js +610 -0
- package/dist/core/blocks/data-driven.d.ts +2 -0
- package/dist/core/blocks/data-driven.js +245 -0
- package/dist/core/blocks/index.d.ts +15 -0
- package/dist/core/blocks/index.js +71 -0
- package/dist/core/blocks/lifecycle.d.ts +2 -0
- package/dist/core/blocks/lifecycle.js +199 -0
- package/dist/core/blocks/logic.d.ts +2 -0
- package/dist/core/blocks/logic.js +357 -0
- package/dist/core/blocks/playwright.d.ts +2 -0
- package/dist/core/blocks/playwright.js +764 -0
- package/dist/core/blocks/procedures.d.ts +5 -0
- package/dist/core/blocks/procedures.js +321 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +44 -0
- package/dist/core/plugins.d.ts +66 -0
- package/dist/core/plugins.js +118 -0
- package/dist/core/types.d.ts +153 -0
- package/dist/core/types.js +2 -0
- package/dist/server/codegenManager.d.ts +54 -0
- package/dist/server/codegenManager.js +259 -0
- package/dist/server/codegenParser.d.ts +17 -0
- package/dist/server/codegenParser.js +598 -0
- package/dist/server/executor.d.ts +37 -0
- package/dist/server/executor.js +672 -0
- package/dist/server/globals.d.ts +85 -0
- package/dist/server/globals.js +273 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +361 -0
- package/dist/server/plugins.d.ts +55 -0
- package/dist/server/plugins.js +206 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 TestBlocks Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# TestBlocks
|
|
2
|
+
|
|
3
|
+
A visual test automation tool using Blockly for building API and web (Playwright) tests. Design tests visually, save them as JSON files for version control, and run them in CI with the CLI runner.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Visual Test Builder** - Drag-and-drop blocks to create tests without coding
|
|
8
|
+
- **API Testing** - Built-in blocks for HTTP requests (GET, POST, PUT, PATCH, DELETE) and assertions
|
|
9
|
+
- **Web Testing** - Playwright-powered blocks for browser automation (navigate, click, type, assertions)
|
|
10
|
+
- **Git-Friendly** - Tests saved as JSON files that can be versioned in repositories
|
|
11
|
+
- **CLI Runner** - Run tests in CI/CD pipelines with JUnit/JSON reports
|
|
12
|
+
- **Extensible** - Create custom blocks with the plugin system
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Install dependencies
|
|
20
|
+
npm install
|
|
21
|
+
|
|
22
|
+
# Build all packages
|
|
23
|
+
npm run build
|
|
24
|
+
|
|
25
|
+
# Install Playwright browsers
|
|
26
|
+
npx playwright install chromium
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Development
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Start the development server (frontend + backend)
|
|
33
|
+
npm run dev
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Open http://localhost:3000 in your browser to use the visual editor.
|
|
37
|
+
|
|
38
|
+
### Running Tests
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Run tests via CLI
|
|
42
|
+
npm run cli run "examples/tests/*.testblocks.json"
|
|
43
|
+
|
|
44
|
+
# Run with headed browser (visible)
|
|
45
|
+
npm run cli run tests/*.testblocks.json --headed
|
|
46
|
+
|
|
47
|
+
# Run with JUnit output for CI
|
|
48
|
+
npm run cli run tests/*.testblocks.json --reporter junit --output ./results
|
|
49
|
+
|
|
50
|
+
# Validate test files
|
|
51
|
+
npm run cli validate "examples/tests/*.testblocks.json"
|
|
52
|
+
|
|
53
|
+
# List tests in files
|
|
54
|
+
npm run cli list "examples/tests/*.testblocks.json"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Project Structure
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
testblocks/
|
|
61
|
+
├── src/
|
|
62
|
+
│ ├── core/ # Types, block definitions, plugin system
|
|
63
|
+
│ ├── client/ # React + Blockly visual editor
|
|
64
|
+
│ ├── server/ # Express server for test execution
|
|
65
|
+
│ └── cli/ # CLI runner for CI integration
|
|
66
|
+
├── examples/
|
|
67
|
+
│ ├── tests/ # Example test files
|
|
68
|
+
│ └── plugins/ # Example custom plugins
|
|
69
|
+
└── testblocks.config.json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Test File Format
|
|
73
|
+
|
|
74
|
+
Tests are stored as `.testblocks.json` files:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"version": "1.0.0",
|
|
79
|
+
"name": "My Test Suite",
|
|
80
|
+
"variables": {
|
|
81
|
+
"baseUrl": { "type": "string", "default": "https://example.com" }
|
|
82
|
+
},
|
|
83
|
+
"beforeAll": [],
|
|
84
|
+
"afterAll": [],
|
|
85
|
+
"beforeEach": [],
|
|
86
|
+
"afterEach": [],
|
|
87
|
+
"procedures": {
|
|
88
|
+
"login": {
|
|
89
|
+
"name": "login",
|
|
90
|
+
"params": [{ "name": "username", "type": "string" }],
|
|
91
|
+
"steps": []
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"tests": [
|
|
95
|
+
{
|
|
96
|
+
"id": "test-1",
|
|
97
|
+
"name": "Login test",
|
|
98
|
+
"data": [
|
|
99
|
+
{ "name": "admin", "values": { "username": "admin", "password": "123" } },
|
|
100
|
+
{ "name": "user", "values": { "username": "user", "password": "456" } }
|
|
101
|
+
],
|
|
102
|
+
"steps": []
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Lifecycle Hooks
|
|
109
|
+
|
|
110
|
+
TestBlocks supports setup/teardown hooks at multiple levels:
|
|
111
|
+
|
|
112
|
+
| Hook | Level | Description |
|
|
113
|
+
|------|-------|-------------|
|
|
114
|
+
| `beforeAll` | Suite | Runs once before all tests |
|
|
115
|
+
| `afterAll` | Suite | Runs once after all tests |
|
|
116
|
+
| `beforeEach` | Suite | Runs before each test |
|
|
117
|
+
| `afterEach` | Suite | Runs after each test |
|
|
118
|
+
| `beforeEach` | Test | Runs before this specific test |
|
|
119
|
+
| `afterEach` | Test | Runs after this specific test |
|
|
120
|
+
|
|
121
|
+
## Data-Driven Testing
|
|
122
|
+
|
|
123
|
+
Run the same test with different data sets:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"id": "test-login",
|
|
128
|
+
"name": "Login with credentials",
|
|
129
|
+
"data": [
|
|
130
|
+
{ "name": "admin user", "values": { "username": "admin", "password": "admin123" } },
|
|
131
|
+
{ "name": "regular user", "values": { "username": "user1", "password": "pass123" } }
|
|
132
|
+
],
|
|
133
|
+
"steps": []
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Access data values using `data_get_current` block with the key name, or use `${username}` variable syntax.
|
|
138
|
+
|
|
139
|
+
## Custom Procedures
|
|
140
|
+
|
|
141
|
+
Define reusable action sequences (like functions):
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"procedures": {
|
|
146
|
+
"login": {
|
|
147
|
+
"name": "login",
|
|
148
|
+
"description": "Login with credentials",
|
|
149
|
+
"params": [
|
|
150
|
+
{ "name": "username", "type": "string" },
|
|
151
|
+
{ "name": "password", "type": "string" }
|
|
152
|
+
],
|
|
153
|
+
"steps": []
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Call procedures using the `procedure_call` block with arguments.
|
|
160
|
+
|
|
161
|
+
## Built-in Blocks
|
|
162
|
+
|
|
163
|
+
### API Blocks
|
|
164
|
+
|
|
165
|
+
| Block | Description |
|
|
166
|
+
|-------|-------------|
|
|
167
|
+
| `GET` | Perform HTTP GET request |
|
|
168
|
+
| `POST` | Perform HTTP POST request |
|
|
169
|
+
| `PUT` | Perform HTTP PUT request |
|
|
170
|
+
| `PATCH` | Perform HTTP PATCH request |
|
|
171
|
+
| `DELETE` | Perform HTTP DELETE request |
|
|
172
|
+
| `Assert Status` | Assert response status code |
|
|
173
|
+
| `Assert Body Contains` | Assert response body contains value |
|
|
174
|
+
| `Extract Value` | Extract value from response using JSON path |
|
|
175
|
+
| `Headers` | Create headers with authentication |
|
|
176
|
+
| `JSON Body` | Create JSON request body |
|
|
177
|
+
|
|
178
|
+
### Web (Playwright) Blocks
|
|
179
|
+
|
|
180
|
+
| Block | Description |
|
|
181
|
+
|-------|-------------|
|
|
182
|
+
| `Navigate` | Navigate to URL |
|
|
183
|
+
| `Click` | Click an element |
|
|
184
|
+
| `Fill` | Fill input field (clears first) |
|
|
185
|
+
| `Type` | Type text character by character |
|
|
186
|
+
| `Select` | Select dropdown option |
|
|
187
|
+
| `Checkbox` | Check/uncheck checkbox |
|
|
188
|
+
| `Hover` | Hover over element |
|
|
189
|
+
| `Press Key` | Press keyboard key |
|
|
190
|
+
| `Wait for Element` | Wait for element state |
|
|
191
|
+
| `Wait for URL` | Wait for URL to match |
|
|
192
|
+
| `Wait` | Pause for specified time |
|
|
193
|
+
| `Screenshot` | Take screenshot |
|
|
194
|
+
| `Get Text` | Get element text content |
|
|
195
|
+
| `Get Attribute` | Get element attribute |
|
|
196
|
+
| `Assert Visible` | Assert element is visible |
|
|
197
|
+
| `Assert Text Contains` | Assert element text contains value |
|
|
198
|
+
| `Assert Text Equals` | Assert element text equals value |
|
|
199
|
+
| `Assert URL Contains` | Assert URL contains value |
|
|
200
|
+
| `Assert Title Contains` | Assert page title contains value |
|
|
201
|
+
|
|
202
|
+
### Logic Blocks
|
|
203
|
+
|
|
204
|
+
| Block | Description |
|
|
205
|
+
|-------|-------------|
|
|
206
|
+
| `Set Variable` | Set a variable value |
|
|
207
|
+
| `Get Variable` | Get a variable value |
|
|
208
|
+
| `If` | Conditional execution |
|
|
209
|
+
| `Compare` | Compare two values |
|
|
210
|
+
| `Repeat` | Repeat blocks N times |
|
|
211
|
+
| `For Each` | Iterate over array |
|
|
212
|
+
| `Try/Catch` | Handle errors |
|
|
213
|
+
| `Log` | Log a message |
|
|
214
|
+
| `Assert` | Assert condition is true |
|
|
215
|
+
| `Fail` | Fail the test |
|
|
216
|
+
|
|
217
|
+
## CLI Options
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
Usage: testblocks run [options] <patterns...>
|
|
221
|
+
|
|
222
|
+
Run test files
|
|
223
|
+
|
|
224
|
+
Options:
|
|
225
|
+
-H, --headed Run in headed mode (show browser)
|
|
226
|
+
-t, --timeout <ms> Test timeout in milliseconds (default: 30000)
|
|
227
|
+
-r, --reporter <type> Reporter: console, json, junit (default: console)
|
|
228
|
+
-o, --output <dir> Output directory for reports
|
|
229
|
+
-b, --base-url <url> Base URL for relative URLs
|
|
230
|
+
-v, --var <vars...> Variables in key=value format
|
|
231
|
+
--fail-fast Stop on first test failure
|
|
232
|
+
--filter <pattern> Only run tests matching pattern
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Creating Custom Plugins
|
|
236
|
+
|
|
237
|
+
Create plugins to add custom blocks:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { createPlugin, createBlock, registerPlugin } from '@testblocks/core';
|
|
241
|
+
|
|
242
|
+
const myPlugin = createPlugin({
|
|
243
|
+
name: 'my-plugin',
|
|
244
|
+
version: '1.0.0',
|
|
245
|
+
description: 'My custom blocks',
|
|
246
|
+
blocks: [
|
|
247
|
+
createBlock({
|
|
248
|
+
type: 'my_custom_block',
|
|
249
|
+
category: 'Custom',
|
|
250
|
+
color: '#9C27B0',
|
|
251
|
+
tooltip: 'My custom action',
|
|
252
|
+
inputs: [
|
|
253
|
+
{ name: 'VALUE', type: 'field', fieldType: 'text', required: true },
|
|
254
|
+
],
|
|
255
|
+
previousStatement: true,
|
|
256
|
+
nextStatement: true,
|
|
257
|
+
execute: async (params, context) => {
|
|
258
|
+
context.logger.info(`Custom block executed with: ${params.VALUE}`);
|
|
259
|
+
},
|
|
260
|
+
}),
|
|
261
|
+
],
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
registerPlugin(myPlugin);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Configuration
|
|
268
|
+
|
|
269
|
+
Create `testblocks.config.json` in your project root:
|
|
270
|
+
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"testDir": "./tests",
|
|
274
|
+
"testMatch": ["**/*.testblocks.json"],
|
|
275
|
+
"timeout": 30000,
|
|
276
|
+
"headless": true,
|
|
277
|
+
"reporter": "console",
|
|
278
|
+
"outputDir": "./testblocks-results",
|
|
279
|
+
"variables": {
|
|
280
|
+
"baseUrl": "http://localhost:3000"
|
|
281
|
+
},
|
|
282
|
+
"plugins": []
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## CI/CD Integration
|
|
287
|
+
|
|
288
|
+
### GitHub Actions
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
name: Tests
|
|
292
|
+
on: [push, pull_request]
|
|
293
|
+
|
|
294
|
+
jobs:
|
|
295
|
+
test:
|
|
296
|
+
runs-on: ubuntu-latest
|
|
297
|
+
steps:
|
|
298
|
+
- uses: actions/checkout@v4
|
|
299
|
+
|
|
300
|
+
- uses: actions/setup-node@v4
|
|
301
|
+
with:
|
|
302
|
+
node-version: '20'
|
|
303
|
+
|
|
304
|
+
- run: npm ci
|
|
305
|
+
- run: npm run build
|
|
306
|
+
- run: npx playwright install chromium
|
|
307
|
+
|
|
308
|
+
- run: npm run cli run "tests/**/*.testblocks.json" --reporter junit --output results
|
|
309
|
+
|
|
310
|
+
- uses: actions/upload-artifact@v4
|
|
311
|
+
if: always()
|
|
312
|
+
with:
|
|
313
|
+
name: test-results
|
|
314
|
+
path: results/
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### GitLab CI
|
|
318
|
+
|
|
319
|
+
```yaml
|
|
320
|
+
test:
|
|
321
|
+
image: mcr.microsoft.com/playwright:v1.49.0
|
|
322
|
+
script:
|
|
323
|
+
- npm ci
|
|
324
|
+
- npm run build
|
|
325
|
+
- npm run cli run "tests/**/*.testblocks.json" --reporter junit --output results
|
|
326
|
+
artifacts:
|
|
327
|
+
reports:
|
|
328
|
+
junit: results/junit.xml
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TestFile, TestCase, TestResult, Plugin, TestDataSet } from '../core';
|
|
2
|
+
export interface ExecutorOptions {
|
|
3
|
+
headless?: boolean;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
variables?: Record<string, unknown>;
|
|
7
|
+
plugins?: Plugin[];
|
|
8
|
+
}
|
|
9
|
+
export declare class TestExecutor {
|
|
10
|
+
private options;
|
|
11
|
+
private browser;
|
|
12
|
+
private browserContext;
|
|
13
|
+
private page;
|
|
14
|
+
private plugins;
|
|
15
|
+
private procedures;
|
|
16
|
+
constructor(options?: ExecutorOptions);
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
cleanup(): Promise<void>;
|
|
19
|
+
runTestFile(testFile: TestFile): Promise<TestResult[]>;
|
|
20
|
+
private createBaseContext;
|
|
21
|
+
runTestWithData(test: TestCase, testFile: TestFile, dataSet: TestDataSet, dataIndex: number): Promise<TestResult>;
|
|
22
|
+
runTest(test: TestCase, testFile: TestFile): Promise<TestResult>;
|
|
23
|
+
private runSteps;
|
|
24
|
+
private resolveVariableDefaults;
|
|
25
|
+
private extractStepsFromBlocklyState;
|
|
26
|
+
private blocksToSteps;
|
|
27
|
+
private blockToStep;
|
|
28
|
+
private runStep;
|
|
29
|
+
private executeProcedure;
|
|
30
|
+
private resolveParams;
|
|
31
|
+
private createLogger;
|
|
32
|
+
}
|