meross-cli 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/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/cli/commands/control/execute.js +23 -0
- package/cli/commands/control/index.js +12 -0
- package/cli/commands/control/menu.js +193 -0
- package/cli/commands/control/params/generic.js +229 -0
- package/cli/commands/control/params/index.js +56 -0
- package/cli/commands/control/params/light.js +188 -0
- package/cli/commands/control/params/thermostat.js +166 -0
- package/cli/commands/control/params/timer.js +242 -0
- package/cli/commands/control/params/trigger.js +206 -0
- package/cli/commands/dump.js +35 -0
- package/cli/commands/index.js +34 -0
- package/cli/commands/info.js +221 -0
- package/cli/commands/list.js +112 -0
- package/cli/commands/mqtt.js +187 -0
- package/cli/commands/sniffer/device-sniffer.js +217 -0
- package/cli/commands/sniffer/fake-app.js +233 -0
- package/cli/commands/sniffer/index.js +7 -0
- package/cli/commands/sniffer/message-queue.js +65 -0
- package/cli/commands/sniffer/sniffer-menu.js +676 -0
- package/cli/commands/stats.js +90 -0
- package/cli/commands/status/device-status.js +1403 -0
- package/cli/commands/status/hub-status.js +72 -0
- package/cli/commands/status/index.js +50 -0
- package/cli/commands/status/subdevices/hub-smoke-detector.js +82 -0
- package/cli/commands/status/subdevices/hub-temp-hum-sensor.js +43 -0
- package/cli/commands/status/subdevices/hub-thermostat-valve.js +83 -0
- package/cli/commands/status/subdevices/hub-water-leak-sensor.js +27 -0
- package/cli/commands/status/subdevices/index.js +23 -0
- package/cli/commands/test/index.js +185 -0
- package/cli/config/users.js +108 -0
- package/cli/control-registry.js +875 -0
- package/cli/helpers/client.js +89 -0
- package/cli/helpers/meross.js +106 -0
- package/cli/menu/index.js +10 -0
- package/cli/menu/main.js +648 -0
- package/cli/menu/settings.js +789 -0
- package/cli/meross-cli.js +547 -0
- package/cli/tests/README.md +365 -0
- package/cli/tests/test-alarm.js +144 -0
- package/cli/tests/test-child-lock.js +248 -0
- package/cli/tests/test-config.js +133 -0
- package/cli/tests/test-control.js +189 -0
- package/cli/tests/test-diffuser.js +505 -0
- package/cli/tests/test-dnd.js +246 -0
- package/cli/tests/test-electricity.js +209 -0
- package/cli/tests/test-encryption.js +281 -0
- package/cli/tests/test-garage.js +259 -0
- package/cli/tests/test-helper.js +313 -0
- package/cli/tests/test-hub-mts100.js +355 -0
- package/cli/tests/test-hub-sensors.js +489 -0
- package/cli/tests/test-light.js +253 -0
- package/cli/tests/test-presence.js +497 -0
- package/cli/tests/test-registry.js +419 -0
- package/cli/tests/test-roller-shutter.js +628 -0
- package/cli/tests/test-runner.js +415 -0
- package/cli/tests/test-runtime.js +234 -0
- package/cli/tests/test-screen.js +133 -0
- package/cli/tests/test-sensor-history.js +146 -0
- package/cli/tests/test-smoke-config.js +138 -0
- package/cli/tests/test-spray.js +131 -0
- package/cli/tests/test-temp-unit.js +133 -0
- package/cli/tests/test-template.js +238 -0
- package/cli/tests/test-thermostat.js +919 -0
- package/cli/tests/test-timer.js +372 -0
- package/cli/tests/test-toggle.js +342 -0
- package/cli/tests/test-trigger.js +279 -0
- package/cli/utils/display.js +86 -0
- package/cli/utils/terminal.js +137 -0
- package/package.json +53 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Meross Cloud Tests
|
|
2
|
+
|
|
3
|
+
This directory contains test files for the Meross Cloud library. The test system uses a custom lightweight test runner with no external test framework dependencies.
|
|
4
|
+
|
|
5
|
+
## Test System Architecture
|
|
6
|
+
|
|
7
|
+
The test system is designed for simplicity, maintainability, and excellent error reporting:
|
|
8
|
+
|
|
9
|
+
- **Custom Test Runner**: Lightweight async execution engine (no Mocha dependency)
|
|
10
|
+
- **Explicit Dependency Injection**: All dependencies passed via context object (no globals)
|
|
11
|
+
- **Structured Results**: Detailed test results with device context and error information
|
|
12
|
+
- **Better Error Reporting**: Rich error messages with device names and stack traces
|
|
13
|
+
|
|
14
|
+
## Test Files
|
|
15
|
+
|
|
16
|
+
- `test-runner.js` - Custom lightweight test runner for CLI integration
|
|
17
|
+
- `test-registry.js` - Centralized test metadata and auto-discovery
|
|
18
|
+
- `test-helper.js` - Pure utility functions for device discovery and connection management
|
|
19
|
+
- `test-template.js` - Template/example showing new test file structure
|
|
20
|
+
- `test-toggle.js` - Tests for toggle/switch devices
|
|
21
|
+
- `test-light.js` - Tests for light/RGB devices
|
|
22
|
+
- `test-thermostat.js` - Tests for thermostat devices
|
|
23
|
+
- `test-roller-shutter.js` - Tests for roller shutter devices
|
|
24
|
+
- `test-garage.js` - Tests for garage door opener devices
|
|
25
|
+
- `test-spray.js` - Tests for spray/humidifier devices
|
|
26
|
+
- `test-diffuser.js` - Tests for diffuser devices
|
|
27
|
+
- `test-electricity.js` - Tests for electricity/consumption monitoring devices
|
|
28
|
+
- `test-dnd.js` - Tests for Do-Not-Disturb (DND) mode functionality
|
|
29
|
+
- `test-child-lock.js` - Tests for physical lock/child lock functionality
|
|
30
|
+
- `test-timer.js` - Tests for timer functionality (TimerX namespace)
|
|
31
|
+
- `test-trigger.js` - Tests for trigger functionality (TriggerX namespace)
|
|
32
|
+
- `test-alarm.js` - Tests for alarm functionality
|
|
33
|
+
- `test-runtime.js` - Tests for runtime information
|
|
34
|
+
- `test-encryption.js` - Tests for encryption support
|
|
35
|
+
- `test-hub-sensors.js` - Tests for hub sensors (temperature/humidity, water leak, smoke, battery)
|
|
36
|
+
- `test-hub-mts100.js` - Tests for hub MTS100 thermostat valves
|
|
37
|
+
- `test-screen.js` - Tests for screen brightness
|
|
38
|
+
- `test-sensor-history.js` - Tests for sensor history
|
|
39
|
+
- `test-smoke-config.js` - Tests for smoke sensor configuration
|
|
40
|
+
- `test-temp-unit.js` - Tests for temperature unit configuration
|
|
41
|
+
- `test-config.js` - Tests for config features (over temp)
|
|
42
|
+
- `test-control.js` - Tests for control features (multiple commands, upgrade, over temp)
|
|
43
|
+
- `test-presence.js` - Tests for presence sensor devices
|
|
44
|
+
|
|
45
|
+
## Running Tests
|
|
46
|
+
|
|
47
|
+
Tests are only available via the CLI tool. They cannot be run directly with npm or mocha.
|
|
48
|
+
|
|
49
|
+
### Prerequisites
|
|
50
|
+
|
|
51
|
+
Set environment variables for authentication:
|
|
52
|
+
```bash
|
|
53
|
+
export MEROSS_EMAIL="your-email@example.com"
|
|
54
|
+
export MEROSS_PASSWORD="your-password"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Optional: Use cached credentials (base64 encoded token data):
|
|
58
|
+
```bash
|
|
59
|
+
export MEROSS_TOKEN_DATA="base64-encoded-credentials"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Run Tests via CLI
|
|
63
|
+
|
|
64
|
+
Start the CLI in interactive mode:
|
|
65
|
+
```bash
|
|
66
|
+
npm run cli
|
|
67
|
+
# or
|
|
68
|
+
meross-cli interactive
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then run tests:
|
|
72
|
+
```bash
|
|
73
|
+
meross> test electricity
|
|
74
|
+
meross> test toggle
|
|
75
|
+
meross> test light
|
|
76
|
+
# etc.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or run directly from command line:
|
|
80
|
+
```bash
|
|
81
|
+
meross-cli test electricity --email your@email.com --password yourpass
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Available Test Types
|
|
85
|
+
|
|
86
|
+
- `toggle` (or `switch`) - Toggle/switch devices
|
|
87
|
+
- `light` (or `rgb`, `lamp`) - Light/RGB devices
|
|
88
|
+
- `thermostat` - Thermostat devices
|
|
89
|
+
- `roller-shutter` (or `shutter`, `blind`) - Roller shutter devices
|
|
90
|
+
- `garage` - Garage door opener devices
|
|
91
|
+
- `spray` - Spray/humidifier devices
|
|
92
|
+
- `diffuser` - Diffuser devices
|
|
93
|
+
- `electricity` - Electricity/consumption monitoring devices
|
|
94
|
+
- `dnd` - Do-Not-Disturb mode
|
|
95
|
+
- `child-lock` - Physical lock/child lock
|
|
96
|
+
- `timer` - Timer functionality
|
|
97
|
+
- `trigger` - Trigger functionality
|
|
98
|
+
- `alarm` - Alarm functionality
|
|
99
|
+
- `runtime` - Runtime information
|
|
100
|
+
- `encryption` - Encryption support
|
|
101
|
+
- `hub-sensors` (or `hub`) - Hub sensors (temperature/humidity, water leak, smoke, battery)
|
|
102
|
+
- `hub-mts100` (or `mts100`) - Hub MTS100 thermostat valves
|
|
103
|
+
- `screen` - Screen brightness
|
|
104
|
+
- `sensor-history` - Sensor history
|
|
105
|
+
- `smoke-config` - Smoke sensor configuration
|
|
106
|
+
- `temp-unit` - Temperature unit configuration
|
|
107
|
+
- `config` - Config features (over temp)
|
|
108
|
+
- `control` - Control features (multiple commands, upgrade, over temp)
|
|
109
|
+
- `presence` - Presence sensor devices
|
|
110
|
+
|
|
111
|
+
## Writing New Tests
|
|
112
|
+
|
|
113
|
+
### Test File Structure
|
|
114
|
+
|
|
115
|
+
Each test file follows this structure:
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
'use strict';
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Test Description
|
|
122
|
+
* Brief description of what this test covers
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
const { findDevicesByAbility, getDeviceName, OnlineStatus } = require('./test-helper');
|
|
126
|
+
|
|
127
|
+
// Export metadata object
|
|
128
|
+
const metadata = {
|
|
129
|
+
name: 'test-name',
|
|
130
|
+
description: 'Brief description of the test',
|
|
131
|
+
requiredAbilities: ['Appliance.Control.Namespace'],
|
|
132
|
+
aliases: ['alias1', 'alias2'], // Optional
|
|
133
|
+
minDevices: 1
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Export runTests function
|
|
137
|
+
async function runTests(context) {
|
|
138
|
+
const { manager, devices, options = {} } = context;
|
|
139
|
+
const timeout = options.timeout || 30000;
|
|
140
|
+
const results = [];
|
|
141
|
+
|
|
142
|
+
// If no devices provided, discover them
|
|
143
|
+
let testDevices = devices || [];
|
|
144
|
+
if (testDevices.length === 0) {
|
|
145
|
+
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.Namespace', OnlineStatus.ONLINE);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (testDevices.length === 0) {
|
|
149
|
+
results.push({
|
|
150
|
+
name: 'should perform test action',
|
|
151
|
+
passed: false,
|
|
152
|
+
skipped: true,
|
|
153
|
+
error: 'No suitable devices found',
|
|
154
|
+
device: null
|
|
155
|
+
});
|
|
156
|
+
return results;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const testDevice = testDevices[0];
|
|
160
|
+
const deviceName = getDeviceName(testDevice);
|
|
161
|
+
|
|
162
|
+
// Test 1: Perform some action
|
|
163
|
+
try {
|
|
164
|
+
const result = await testDevice.someMethod();
|
|
165
|
+
|
|
166
|
+
if (!result) {
|
|
167
|
+
results.push({
|
|
168
|
+
name: 'should perform test action',
|
|
169
|
+
passed: false,
|
|
170
|
+
skipped: false,
|
|
171
|
+
error: 'Method returned null or undefined',
|
|
172
|
+
device: deviceName
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
results.push({
|
|
176
|
+
name: 'should perform test action',
|
|
177
|
+
passed: true,
|
|
178
|
+
skipped: false,
|
|
179
|
+
error: null,
|
|
180
|
+
device: deviceName,
|
|
181
|
+
details: { result: result }
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
results.push({
|
|
186
|
+
name: 'should perform test action',
|
|
187
|
+
passed: false,
|
|
188
|
+
skipped: false,
|
|
189
|
+
error: error.message,
|
|
190
|
+
device: deviceName
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return results;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = {
|
|
198
|
+
metadata,
|
|
199
|
+
runTests
|
|
200
|
+
};
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Key Points
|
|
204
|
+
|
|
205
|
+
1. **Metadata Export**: Every test file must export a `metadata` object with:
|
|
206
|
+
- `name`: Test type identifier
|
|
207
|
+
- `description`: Human-readable description
|
|
208
|
+
- `requiredAbilities`: Array of ability namespaces required
|
|
209
|
+
- `aliases`: Optional array of alternative names
|
|
210
|
+
- `minDevices`: Minimum number of devices required (default: 1)
|
|
211
|
+
|
|
212
|
+
2. **runTests Function**: Must accept a `context` object with:
|
|
213
|
+
- `manager`: MerossManager instance
|
|
214
|
+
- `devices`: Array of pre-selected devices (optional, will auto-discover if not provided)
|
|
215
|
+
- `options`: Test options (timeout, verbose, etc.)
|
|
216
|
+
|
|
217
|
+
3. **Return Value**: Must return an array of test result objects:
|
|
218
|
+
```javascript
|
|
219
|
+
{
|
|
220
|
+
name: 'Test name',
|
|
221
|
+
passed: true/false,
|
|
222
|
+
skipped: true/false,
|
|
223
|
+
error: 'Error message or null',
|
|
224
|
+
device: 'Device name or null',
|
|
225
|
+
details: { /* optional additional info */ }
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
4. **No Globals**: All dependencies are passed explicitly via the context object.
|
|
230
|
+
|
|
231
|
+
5. **Error Handling**: Always wrap test logic in try-catch blocks and return structured results.
|
|
232
|
+
|
|
233
|
+
### Test Helper Functions
|
|
234
|
+
|
|
235
|
+
The `test-helper.js` module provides pure utility functions:
|
|
236
|
+
|
|
237
|
+
- `waitForDevices(manager, timeout)` - Wait for devices to be discovered
|
|
238
|
+
- `findDevicesByAbility(manager, namespace, onlineStatus)` - Find devices by ability namespace
|
|
239
|
+
- `findDevicesByType(manager, deviceType, onlineStatus)` - Find devices by device type
|
|
240
|
+
- `waitForDeviceConnection(device, timeout)` - Wait for device to connect
|
|
241
|
+
- `waitForPushNotification(device, namespace, timeout)` - Wait for push notification
|
|
242
|
+
- `getDeviceName(device)` - Get device display name
|
|
243
|
+
- `deviceHasAbility(device, namespace)` - Check if device has specific ability
|
|
244
|
+
- `getDeviceOnlineStatus(device)` - Get device online status
|
|
245
|
+
|
|
246
|
+
All functions accept explicit parameters - no globals or environment variables.
|
|
247
|
+
|
|
248
|
+
### Example: Simple Test
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
'use strict';
|
|
252
|
+
|
|
253
|
+
const { findDevicesByAbility, getDeviceName, OnlineStatus } = require('./test-helper');
|
|
254
|
+
|
|
255
|
+
const metadata = {
|
|
256
|
+
name: 'simple-test',
|
|
257
|
+
description: 'Tests simple device functionality',
|
|
258
|
+
requiredAbilities: ['Appliance.Control.Simple'],
|
|
259
|
+
minDevices: 1
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
async function runTests(context) {
|
|
263
|
+
const { manager, devices } = context;
|
|
264
|
+
const results = [];
|
|
265
|
+
|
|
266
|
+
let testDevices = devices || [];
|
|
267
|
+
if (testDevices.length === 0) {
|
|
268
|
+
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.Simple', OnlineStatus.ONLINE);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (testDevices.length === 0) {
|
|
272
|
+
results.push({
|
|
273
|
+
name: 'should find devices',
|
|
274
|
+
passed: false,
|
|
275
|
+
skipped: true,
|
|
276
|
+
error: 'No devices found',
|
|
277
|
+
device: null
|
|
278
|
+
});
|
|
279
|
+
return results;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const device = testDevices[0];
|
|
283
|
+
const deviceName = getDeviceName(device);
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
const state = await device.getState();
|
|
287
|
+
results.push({
|
|
288
|
+
name: 'should get device state',
|
|
289
|
+
passed: !!state,
|
|
290
|
+
skipped: false,
|
|
291
|
+
error: state ? null : 'State is null',
|
|
292
|
+
device: deviceName
|
|
293
|
+
});
|
|
294
|
+
} catch (error) {
|
|
295
|
+
results.push({
|
|
296
|
+
name: 'should get device state',
|
|
297
|
+
passed: false,
|
|
298
|
+
skipped: false,
|
|
299
|
+
error: error.message,
|
|
300
|
+
device: deviceName
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return results;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
module.exports = { metadata, runTests };
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Test Results Format
|
|
311
|
+
|
|
312
|
+
Test results are returned in a structured format:
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
{
|
|
316
|
+
success: true/false, // Overall success status
|
|
317
|
+
passed: 5, // Number of passed tests
|
|
318
|
+
failed: 1, // Number of failed tests
|
|
319
|
+
skipped: 2, // Number of skipped tests
|
|
320
|
+
duration: 12345, // Duration in milliseconds
|
|
321
|
+
error: 'Error message or null', // Overall error (if any)
|
|
322
|
+
stack: 'Stack trace', // Stack trace (if error)
|
|
323
|
+
tests: [ // Array of individual test results
|
|
324
|
+
{
|
|
325
|
+
name: 'Test name',
|
|
326
|
+
passed: true/false,
|
|
327
|
+
skipped: true/false,
|
|
328
|
+
error: 'Error message or null',
|
|
329
|
+
device: 'Device name',
|
|
330
|
+
details: { /* optional */ }
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Debugging
|
|
337
|
+
|
|
338
|
+
The test runner provides detailed error reporting:
|
|
339
|
+
|
|
340
|
+
- **Device Context**: Each test result includes the device name
|
|
341
|
+
- **Error Messages**: Clear error messages with context
|
|
342
|
+
- **Stack Traces**: Full stack traces for debugging
|
|
343
|
+
- **Progress Indicators**: Shows which device is being tested
|
|
344
|
+
- **Structured Output**: Easy to parse and analyze
|
|
345
|
+
|
|
346
|
+
## Notes
|
|
347
|
+
|
|
348
|
+
- Tests require actual Meross devices to be available in your account
|
|
349
|
+
- Tests will skip if no suitable devices are found
|
|
350
|
+
- Some tests may take longer due to device operations (e.g., garage doors, roller shutters)
|
|
351
|
+
- Push notification tests may require special setup
|
|
352
|
+
- All tests use explicit dependency injection - no globals or environment variables
|
|
353
|
+
|
|
354
|
+
## Migration from Old System
|
|
355
|
+
|
|
356
|
+
The old test system used Mocha/Chai and global variables. The new system:
|
|
357
|
+
|
|
358
|
+
- ✅ No Mocha dependency
|
|
359
|
+
- ✅ No global variables
|
|
360
|
+
- ✅ Explicit dependency injection
|
|
361
|
+
- ✅ Better error reporting
|
|
362
|
+
- ✅ Structured results
|
|
363
|
+
- ✅ Easier to debug
|
|
364
|
+
|
|
365
|
+
See `test-template.js` for a complete example of the new structure.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Alarm Device Tests
|
|
5
|
+
* Tests alarm functionality and notifications
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { findDevicesByAbility, waitForDeviceConnection, getDeviceName, OnlineStatus } = require('./test-helper');
|
|
9
|
+
|
|
10
|
+
const metadata = {
|
|
11
|
+
name: 'alarm',
|
|
12
|
+
description: 'Tests alarm functionality and notifications',
|
|
13
|
+
requiredAbilities: ['Appliance.Control.Alarm'],
|
|
14
|
+
minDevices: 1
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
async function runTests(context) {
|
|
18
|
+
const { manager, devices, options = {} } = context;
|
|
19
|
+
const timeout = options.timeout || 30000;
|
|
20
|
+
const results = [];
|
|
21
|
+
|
|
22
|
+
// If no devices provided, discover them
|
|
23
|
+
let testDevices = devices || [];
|
|
24
|
+
if (testDevices.length === 0) {
|
|
25
|
+
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.Alarm', OnlineStatus.ONLINE);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Wait for devices to be connected
|
|
29
|
+
for (const device of testDevices) {
|
|
30
|
+
await waitForDeviceConnection(device, timeout);
|
|
31
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (testDevices.length === 0) {
|
|
35
|
+
results.push({
|
|
36
|
+
name: 'should get alarm status',
|
|
37
|
+
passed: false,
|
|
38
|
+
skipped: true,
|
|
39
|
+
error: 'No Alarm device has been found to run this test on',
|
|
40
|
+
device: null
|
|
41
|
+
});
|
|
42
|
+
return results;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const testDevice = testDevices[0];
|
|
46
|
+
const deviceName = getDeviceName(testDevice);
|
|
47
|
+
|
|
48
|
+
// Test 1: Get alarm status
|
|
49
|
+
try {
|
|
50
|
+
const response = await testDevice.getAlarmStatus({ channel: 0 });
|
|
51
|
+
|
|
52
|
+
if (!response) {
|
|
53
|
+
results.push({
|
|
54
|
+
name: 'should get alarm status',
|
|
55
|
+
passed: false,
|
|
56
|
+
skipped: false,
|
|
57
|
+
error: 'getAlarmStatus returned null or undefined',
|
|
58
|
+
device: deviceName
|
|
59
|
+
});
|
|
60
|
+
} else if (!Array.isArray(response.alarm)) {
|
|
61
|
+
results.push({
|
|
62
|
+
name: 'should get alarm status',
|
|
63
|
+
passed: false,
|
|
64
|
+
skipped: false,
|
|
65
|
+
error: 'Response alarm is not an array',
|
|
66
|
+
device: deviceName
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
results.push({
|
|
70
|
+
name: 'should get alarm status',
|
|
71
|
+
passed: true,
|
|
72
|
+
skipped: false,
|
|
73
|
+
error: null,
|
|
74
|
+
device: deviceName,
|
|
75
|
+
details: { alarm: response.alarm }
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
results.push({
|
|
80
|
+
name: 'should get alarm status',
|
|
81
|
+
passed: false,
|
|
82
|
+
skipped: false,
|
|
83
|
+
error: error.message,
|
|
84
|
+
device: deviceName
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Test 2: Store alarm events from push notifications
|
|
89
|
+
try {
|
|
90
|
+
// Get initial alarm events (should be empty or existing events)
|
|
91
|
+
const initialEvents = testDevice.getLastAlarmEvents();
|
|
92
|
+
|
|
93
|
+
if (!Array.isArray(initialEvents)) {
|
|
94
|
+
results.push({
|
|
95
|
+
name: 'should store alarm events from push notifications',
|
|
96
|
+
passed: false,
|
|
97
|
+
skipped: false,
|
|
98
|
+
error: 'getLastAlarmEvents did not return an array',
|
|
99
|
+
device: deviceName
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
// Get current alarm status
|
|
103
|
+
await testDevice.getAlarmStatus({ channel: 0 });
|
|
104
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
105
|
+
|
|
106
|
+
// Check that getLastAlarmEvents returns an array (even if empty)
|
|
107
|
+
const events = testDevice.getLastAlarmEvents();
|
|
108
|
+
|
|
109
|
+
if (!Array.isArray(events)) {
|
|
110
|
+
results.push({
|
|
111
|
+
name: 'should store alarm events from push notifications',
|
|
112
|
+
passed: false,
|
|
113
|
+
skipped: false,
|
|
114
|
+
error: 'getLastAlarmEvents did not return an array after getAlarmStatus',
|
|
115
|
+
device: deviceName
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
results.push({
|
|
119
|
+
name: 'should store alarm events from push notifications',
|
|
120
|
+
passed: true,
|
|
121
|
+
skipped: false,
|
|
122
|
+
error: null,
|
|
123
|
+
device: deviceName,
|
|
124
|
+
details: { eventCount: events.length }
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
results.push({
|
|
130
|
+
name: 'should store alarm events from push notifications',
|
|
131
|
+
passed: false,
|
|
132
|
+
skipped: false,
|
|
133
|
+
error: error.message,
|
|
134
|
+
device: deviceName
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return results;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module.exports = {
|
|
142
|
+
metadata,
|
|
143
|
+
runTests
|
|
144
|
+
};
|