@pilaf/framework 1.0.0 → 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 +218 -0
- package/package.json +9 -5
package/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# @pilaf/framework
|
|
2
|
+
|
|
3
|
+
Jest integration and test framework for Pilaf.
|
|
4
|
+
|
|
5
|
+
Provides the `StoryRunner` for executing declarative test stories against Minecraft servers.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @pilaf/framework
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Peer Dependencies
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add -D jest@^29.0.0
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## StoryRunner
|
|
20
|
+
|
|
21
|
+
The `StoryRunner` executes declarative test stories against Minecraft servers.
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
const { StoryRunner } = require('@pilaf/framework');
|
|
25
|
+
|
|
26
|
+
const runner = new StoryRunner();
|
|
27
|
+
|
|
28
|
+
const story = {
|
|
29
|
+
name: 'My Test Story',
|
|
30
|
+
setup: {
|
|
31
|
+
server: {
|
|
32
|
+
type: 'paper',
|
|
33
|
+
version: '1.21.8',
|
|
34
|
+
rcon: {
|
|
35
|
+
host: 'localhost',
|
|
36
|
+
port: 25575,
|
|
37
|
+
password: 'password'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
players: [
|
|
41
|
+
{
|
|
42
|
+
name: 'Player1',
|
|
43
|
+
username: 'TestPlayer',
|
|
44
|
+
auth: 'offline'
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
steps: [
|
|
49
|
+
{
|
|
50
|
+
name: 'Make player an operator',
|
|
51
|
+
action: 'execute_command',
|
|
52
|
+
command: 'op Player1'
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Execute player command',
|
|
56
|
+
action: 'execute_player_command',
|
|
57
|
+
player: 'Player1',
|
|
58
|
+
command: '/gamemode creative'
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
teardown: {
|
|
62
|
+
stop_server: false,
|
|
63
|
+
disconnect_players: true
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const result = await runner.execute(story);
|
|
68
|
+
console.log(result.success); // true or false
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Story Structure
|
|
72
|
+
|
|
73
|
+
### Setup
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
setup: {
|
|
77
|
+
server: {
|
|
78
|
+
type: 'paper', // Server type (optional)
|
|
79
|
+
version: '1.21.8', // Minecraft version (optional)
|
|
80
|
+
rcon: {
|
|
81
|
+
host: 'localhost',
|
|
82
|
+
port: 25575,
|
|
83
|
+
password: 'password'
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
players: [
|
|
87
|
+
{
|
|
88
|
+
name: 'InternalName', // Reference name in steps
|
|
89
|
+
username: 'MinecraftName',
|
|
90
|
+
auth: 'offline' // or 'microsoft'
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Steps
|
|
97
|
+
|
|
98
|
+
Each step has:
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
{
|
|
102
|
+
name: 'Step description',
|
|
103
|
+
action: 'action_name',
|
|
104
|
+
// action-specific parameters
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Available Actions:**
|
|
109
|
+
|
|
110
|
+
- `execute_command` - Execute RCON command
|
|
111
|
+
- `execute_player_command` - Execute command as player
|
|
112
|
+
- `chat` - Send chat message
|
|
113
|
+
- `move_forward` - Move player forward
|
|
114
|
+
- `wait` - Pause execution
|
|
115
|
+
- `get_entities` - Get nearby entities
|
|
116
|
+
- `get_player_inventory` - Get player inventory
|
|
117
|
+
- `get_player_location` - Get player position
|
|
118
|
+
- `calculate_distance` - Calculate distance between positions
|
|
119
|
+
- `login` / `logout` - Reconnect/disconnect player
|
|
120
|
+
- `respawn` - Respawn player
|
|
121
|
+
- `assert` - Make assertions
|
|
122
|
+
|
|
123
|
+
### Using Stored Values
|
|
124
|
+
|
|
125
|
+
Store results from steps and use them later:
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
steps: [
|
|
129
|
+
{
|
|
130
|
+
name: 'Get position',
|
|
131
|
+
action: 'get_player_location',
|
|
132
|
+
player: 'P1',
|
|
133
|
+
store_as: 'start_pos'
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'Calculate distance',
|
|
137
|
+
action: 'calculate_distance',
|
|
138
|
+
from: '{start_pos}',
|
|
139
|
+
to: '{end_pos}',
|
|
140
|
+
store_as: 'distance'
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Teardown
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
teardown: {
|
|
149
|
+
stop_server: false, // Keep server running
|
|
150
|
+
disconnect_players: true // Disconnect players
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Jest Reporter
|
|
155
|
+
|
|
156
|
+
Pilaf includes a custom Jest reporter that generates HTML reports:
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
// jest.config.js
|
|
160
|
+
module.exports = {
|
|
161
|
+
testMatch: ['**/*.pilaf.test.js'],
|
|
162
|
+
reporters: [
|
|
163
|
+
'default',
|
|
164
|
+
['@pilaf/framework/lib/reporters/pilaf-reporter.js', {
|
|
165
|
+
outputPath: 'target/pilaf-reports/index.html',
|
|
166
|
+
suiteName: 'My Plugin Tests'
|
|
167
|
+
}]
|
|
168
|
+
]
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Helpers
|
|
173
|
+
|
|
174
|
+
### State Management
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
const { captureState, compareStates } = require('@pilaf/framework/lib/helpers/state');
|
|
178
|
+
|
|
179
|
+
// Capture state with deep clone
|
|
180
|
+
const before = captureState(myObject);
|
|
181
|
+
|
|
182
|
+
// Compare states
|
|
183
|
+
const diff = compareStates(before, after);
|
|
184
|
+
console.log(diff.hasChanges); // true or false
|
|
185
|
+
console.log(diff.changes); // Array of changes
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Event Helpers
|
|
189
|
+
|
|
190
|
+
```javascript
|
|
191
|
+
const { waitForEvents, captureEvents } = require('@pilaf/framework/lib/helpers/events');
|
|
192
|
+
|
|
193
|
+
// Wait for events
|
|
194
|
+
const events = await waitForEvents(bot, 'chat', 3, 5000);
|
|
195
|
+
|
|
196
|
+
// Capture events
|
|
197
|
+
const capture = captureEvents(bot, ['chat', 'playerJoined']);
|
|
198
|
+
// ... do stuff ...
|
|
199
|
+
capture.release(); // Clean up listeners
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Matchers
|
|
203
|
+
|
|
204
|
+
Custom Jest matchers for game testing:
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
const { matchers } = require('@pilaf/framework');
|
|
208
|
+
|
|
209
|
+
expect.extend(matchers);
|
|
210
|
+
|
|
211
|
+
// Use in tests
|
|
212
|
+
await expect(player).toHavePosition({ x: 100, y: 64, z: 100 });
|
|
213
|
+
await expect(player).toHaveInventoryItem('diamond');
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilaf/framework",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/cavarest/pilaf"
|
|
8
|
+
},
|
|
5
9
|
"files": [
|
|
6
10
|
"lib/*.js",
|
|
7
11
|
"lib/**/*.js",
|
|
@@ -14,10 +18,10 @@
|
|
|
14
18
|
"access": "public"
|
|
15
19
|
},
|
|
16
20
|
"dependencies": {
|
|
21
|
+
"@pilaf/backends": "workspace:*",
|
|
22
|
+
"@pilaf/reporting": "workspace:*",
|
|
17
23
|
"jest": "^29.7.0",
|
|
18
|
-
"js-yaml": "^4.1.0"
|
|
19
|
-
"@pilaf/backends": "1.0.0",
|
|
20
|
-
"@pilaf/reporting": "1.0.0"
|
|
24
|
+
"js-yaml": "^4.1.0"
|
|
21
25
|
},
|
|
22
26
|
"devDependencies": {
|
|
23
27
|
"@jest/globals": "^29.7.0"
|
|
@@ -25,4 +29,4 @@
|
|
|
25
29
|
"peerDependencies": {
|
|
26
30
|
"jest": ">=29.0.0"
|
|
27
31
|
}
|
|
28
|
-
}
|
|
32
|
+
}
|