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,419 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Test Registry - Centralized metadata and auto-discovery for test files
|
|
8
|
+
*
|
|
9
|
+
* This registry maintains metadata about all available tests including:
|
|
10
|
+
* - Test type names and aliases
|
|
11
|
+
* - File mappings
|
|
12
|
+
* - Descriptions
|
|
13
|
+
* - Required device abilities
|
|
14
|
+
* - Minimum device requirements
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Static test metadata
|
|
19
|
+
* Maps test type names to their configuration
|
|
20
|
+
*
|
|
21
|
+
* Structure:
|
|
22
|
+
* {
|
|
23
|
+
* 'test-type': {
|
|
24
|
+
* file: 'test-file.js',
|
|
25
|
+
* description: 'Test description',
|
|
26
|
+
* requiredAbilities: ['Appliance.Control.X', ...],
|
|
27
|
+
* minDevices: 1,
|
|
28
|
+
* aliases: ['alias1', 'alias2'] // Optional alternative names
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
*/
|
|
32
|
+
const TEST_METADATA = {
|
|
33
|
+
'switch': {
|
|
34
|
+
file: 'test-toggle.js',
|
|
35
|
+
description: 'Tests on/off control for switches and smart plugs',
|
|
36
|
+
requiredAbilities: ['Appliance.Control.ToggleX', 'Appliance.Control.Toggle'],
|
|
37
|
+
minDevices: 1,
|
|
38
|
+
aliases: ['toggle']
|
|
39
|
+
},
|
|
40
|
+
'light': {
|
|
41
|
+
file: 'test-light.js',
|
|
42
|
+
description: 'Tests RGB color, brightness, and temperature control for light devices',
|
|
43
|
+
requiredAbilities: ['Appliance.Control.Light'],
|
|
44
|
+
minDevices: 1,
|
|
45
|
+
aliases: ['rgb', 'lamp']
|
|
46
|
+
},
|
|
47
|
+
'thermostat': {
|
|
48
|
+
file: 'test-thermostat.js',
|
|
49
|
+
description: 'Tests thermostat mode control, temperature settings, and ambient temperature reading',
|
|
50
|
+
requiredAbilities: ['Appliance.Control.Thermostat.Mode'],
|
|
51
|
+
minDevices: 1
|
|
52
|
+
},
|
|
53
|
+
'shutter': {
|
|
54
|
+
file: 'test-roller-shutter.js',
|
|
55
|
+
description: 'Tests open/close control and position setting for roller shutters',
|
|
56
|
+
requiredAbilities: ['Appliance.RollerShutter.State'],
|
|
57
|
+
minDevices: 1,
|
|
58
|
+
aliases: ['roller-shutter', 'blind']
|
|
59
|
+
},
|
|
60
|
+
'garage': {
|
|
61
|
+
file: 'test-garage.js',
|
|
62
|
+
description: 'Tests open/close control for garage door openers',
|
|
63
|
+
requiredAbilities: ['Appliance.GarageDoor.State'],
|
|
64
|
+
minDevices: 1
|
|
65
|
+
},
|
|
66
|
+
'spray': {
|
|
67
|
+
file: 'test-spray.js',
|
|
68
|
+
description: 'Tests spray mode control for spray devices',
|
|
69
|
+
requiredAbilities: ['Appliance.Control.Spray'],
|
|
70
|
+
minDevices: 1
|
|
71
|
+
},
|
|
72
|
+
'diffuser': {
|
|
73
|
+
file: 'test-diffuser.js',
|
|
74
|
+
description: 'Tests light RGB control, brightness, and spray mode for diffuser devices',
|
|
75
|
+
requiredAbilities: ['Appliance.Control.Diffuser.Light', 'Appliance.Control.Diffuser.Spray'],
|
|
76
|
+
minDevices: 1
|
|
77
|
+
},
|
|
78
|
+
'electricity': {
|
|
79
|
+
file: 'test-electricity.js',
|
|
80
|
+
description: 'Tests power consumption metrics and daily consumption data',
|
|
81
|
+
requiredAbilities: ['Appliance.Control.ConsumptionX', 'Appliance.Control.Consumption', 'Appliance.Control.Electricity'],
|
|
82
|
+
minDevices: 1
|
|
83
|
+
},
|
|
84
|
+
'dnd': {
|
|
85
|
+
file: 'test-dnd.js',
|
|
86
|
+
description: 'Tests do-not-disturb mode functionality',
|
|
87
|
+
requiredAbilities: ['Appliance.System.DNDMode'],
|
|
88
|
+
minDevices: 1
|
|
89
|
+
},
|
|
90
|
+
'child-lock': {
|
|
91
|
+
file: 'test-child-lock.js',
|
|
92
|
+
description: 'Tests physical lock/child lock safety features',
|
|
93
|
+
requiredAbilities: ['Appliance.Control.PhysicalLock'],
|
|
94
|
+
minDevices: 1
|
|
95
|
+
},
|
|
96
|
+
'timer': {
|
|
97
|
+
file: 'test-timer.js',
|
|
98
|
+
description: 'Tests timer creation, management, and execution',
|
|
99
|
+
requiredAbilities: ['Appliance.Control.TimerX', 'Appliance.Digest.TimerX'],
|
|
100
|
+
minDevices: 1
|
|
101
|
+
},
|
|
102
|
+
'trigger': {
|
|
103
|
+
file: 'test-trigger.js',
|
|
104
|
+
description: 'Tests trigger configuration and execution',
|
|
105
|
+
requiredAbilities: ['Appliance.Control.TriggerX', 'Appliance.Digest.TriggerX'],
|
|
106
|
+
minDevices: 1
|
|
107
|
+
},
|
|
108
|
+
'alarm': {
|
|
109
|
+
file: 'test-alarm.js',
|
|
110
|
+
description: 'Tests alarm functionality and notifications',
|
|
111
|
+
requiredAbilities: ['Appliance.Control.Alarm'],
|
|
112
|
+
minDevices: 1
|
|
113
|
+
},
|
|
114
|
+
'runtime': {
|
|
115
|
+
file: 'test-runtime.js',
|
|
116
|
+
description: 'Tests device runtime and system runtime information',
|
|
117
|
+
requiredAbilities: ['Appliance.System.Runtime'],
|
|
118
|
+
minDevices: 1
|
|
119
|
+
},
|
|
120
|
+
'encryption': {
|
|
121
|
+
file: 'test-encryption.js',
|
|
122
|
+
description: 'Tests encryption capabilities and secure communication',
|
|
123
|
+
requiredAbilities: ['Appliance.Encrypt.ECDHE', 'Appliance.Encrypt.Suite'],
|
|
124
|
+
minDevices: 1
|
|
125
|
+
},
|
|
126
|
+
'hub': {
|
|
127
|
+
file: 'test-hub-sensors.js',
|
|
128
|
+
description: 'Tests hub sensor discovery and temperature/humidity readings',
|
|
129
|
+
requiredAbilities: ['Appliance.Hub.Sensor.All', 'Appliance.Hub.Sensor.TempHum', 'Appliance.Hub.Battery'],
|
|
130
|
+
minDevices: 1,
|
|
131
|
+
aliases: ['hub-sensors']
|
|
132
|
+
},
|
|
133
|
+
'mts100': {
|
|
134
|
+
file: 'test-hub-mts100.js',
|
|
135
|
+
description: 'Tests MTS100 thermostat hub functionality',
|
|
136
|
+
requiredAbilities: ['Appliance.Hub.Mts100.All'],
|
|
137
|
+
minDevices: 1,
|
|
138
|
+
aliases: ['hub-mts100']
|
|
139
|
+
},
|
|
140
|
+
'screen': {
|
|
141
|
+
file: 'test-screen.js',
|
|
142
|
+
description: 'Tests screen brightness control',
|
|
143
|
+
requiredAbilities: ['Appliance.Control.Screen.Brightness'],
|
|
144
|
+
minDevices: 1
|
|
145
|
+
},
|
|
146
|
+
'sensor-history': {
|
|
147
|
+
file: 'test-sensor-history.js',
|
|
148
|
+
description: 'Tests sensor history data retrieval',
|
|
149
|
+
requiredAbilities: ['Appliance.Control.Sensor.History'],
|
|
150
|
+
minDevices: 1
|
|
151
|
+
},
|
|
152
|
+
'smoke-config': {
|
|
153
|
+
file: 'test-smoke-config.js',
|
|
154
|
+
description: 'Tests smoke detector configuration settings',
|
|
155
|
+
requiredAbilities: ['Appliance.Control.Smoke.Config'],
|
|
156
|
+
minDevices: 1
|
|
157
|
+
},
|
|
158
|
+
'temp-unit': {
|
|
159
|
+
file: 'test-temp-unit.js',
|
|
160
|
+
description: 'Tests temperature unit settings (Celsius/Fahrenheit)',
|
|
161
|
+
requiredAbilities: ['Appliance.Control.TempUnit'],
|
|
162
|
+
minDevices: 1
|
|
163
|
+
},
|
|
164
|
+
'config': {
|
|
165
|
+
file: 'test-config.js',
|
|
166
|
+
description: 'Tests device configuration and settings',
|
|
167
|
+
requiredAbilities: ['Appliance.Config.OverTemp'],
|
|
168
|
+
minDevices: 1
|
|
169
|
+
},
|
|
170
|
+
'control': {
|
|
171
|
+
file: 'test-control.js',
|
|
172
|
+
description: 'Tests multiple control features and device capabilities',
|
|
173
|
+
requiredAbilities: ['Appliance.Control.Multiple', 'Appliance.Control.Upgrade', 'Appliance.Control.OverTemp'],
|
|
174
|
+
minDevices: 1
|
|
175
|
+
},
|
|
176
|
+
'presence': {
|
|
177
|
+
file: 'test-presence.js',
|
|
178
|
+
description: 'Tests presence detection, light readings, and configuration for presence sensor devices',
|
|
179
|
+
requiredAbilities: ['Appliance.Control.Sensor.LatestX'],
|
|
180
|
+
minDevices: 1
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Reverse mapping: alias -> canonical test type name
|
|
186
|
+
* Built automatically from TEST_METADATA
|
|
187
|
+
*/
|
|
188
|
+
let aliasMap = null;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Build alias map from metadata
|
|
192
|
+
* @returns {Object} Map of alias -> canonical name
|
|
193
|
+
*/
|
|
194
|
+
function buildAliasMap() {
|
|
195
|
+
if (aliasMap) {
|
|
196
|
+
return aliasMap;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
aliasMap = {};
|
|
200
|
+
for (const [canonicalName, metadata] of Object.entries(TEST_METADATA)) {
|
|
201
|
+
if (metadata.aliases) {
|
|
202
|
+
for (const alias of metadata.aliases) {
|
|
203
|
+
aliasMap[alias.toLowerCase()] = canonicalName;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Also map canonical name to itself
|
|
207
|
+
aliasMap[canonicalName.toLowerCase()] = canonicalName;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return aliasMap;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Resolves a test type name (handles aliases)
|
|
215
|
+
* @param {string} testType - Test type name or alias
|
|
216
|
+
* @returns {string|null} Canonical test type name or null if not found
|
|
217
|
+
*/
|
|
218
|
+
function resolveTestType(testType) {
|
|
219
|
+
if (!testType) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const aliases = buildAliasMap();
|
|
224
|
+
const normalized = testType.toLowerCase();
|
|
225
|
+
|
|
226
|
+
return aliases[normalized] || (TEST_METADATA[normalized] ? normalized : null);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Gets metadata for a test type
|
|
231
|
+
* @param {string} testType - Test type name or alias
|
|
232
|
+
* @returns {Object|null} Test metadata or null if not found
|
|
233
|
+
*/
|
|
234
|
+
function getTestMetadata(testType) {
|
|
235
|
+
const canonicalName = resolveTestType(testType);
|
|
236
|
+
if (!canonicalName) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return TEST_METADATA[canonicalName] || null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Gets available test types
|
|
245
|
+
* @returns {Array<string>} Array of canonical test type names
|
|
246
|
+
*/
|
|
247
|
+
function getAvailableTestTypes() {
|
|
248
|
+
return Object.keys(TEST_METADATA);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Gets description for a test type
|
|
253
|
+
* @param {string} testType - Test type name or alias
|
|
254
|
+
* @returns {string} Description of the test type
|
|
255
|
+
*/
|
|
256
|
+
function getTestDescription(testType) {
|
|
257
|
+
const metadata = getTestMetadata(testType);
|
|
258
|
+
return metadata ? metadata.description : `Tests ${testType} device functionality`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Gets required abilities for a test type
|
|
263
|
+
* @param {string} testType - Test type name or alias
|
|
264
|
+
* @returns {Array<string>} Array of required ability namespaces
|
|
265
|
+
*/
|
|
266
|
+
function getRequiredAbilities(testType) {
|
|
267
|
+
const metadata = getTestMetadata(testType);
|
|
268
|
+
return metadata ? (metadata.requiredAbilities || []) : [];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Gets minimum number of devices required for a test
|
|
273
|
+
* @param {string} testType - Test type name or alias
|
|
274
|
+
* @returns {number} Minimum number of devices (default: 1)
|
|
275
|
+
*/
|
|
276
|
+
function getMinDevices(testType) {
|
|
277
|
+
const metadata = getTestMetadata(testType);
|
|
278
|
+
return metadata ? (metadata.minDevices || 1) : 1;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Gets test file path for a given test type
|
|
283
|
+
* @param {string} testType - Test type name or alias
|
|
284
|
+
* @param {string} baseDir - Base directory for test files (default: __dirname)
|
|
285
|
+
* @returns {string|null} Path to test file or null if not found
|
|
286
|
+
*/
|
|
287
|
+
function getTestFile(testType, baseDir = __dirname) {
|
|
288
|
+
const metadata = getTestMetadata(testType);
|
|
289
|
+
if (!metadata || !metadata.file) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const testPath = path.join(baseDir, metadata.file);
|
|
294
|
+
if (fs.existsSync(testPath)) {
|
|
295
|
+
return testPath;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Auto-discovers test files in the tests directory
|
|
303
|
+
* Scans for test-*.js files and attempts to load their metadata
|
|
304
|
+
* @param {string} baseDir - Base directory to scan (default: __dirname)
|
|
305
|
+
* @returns {Array<Object>} Array of discovered test info objects
|
|
306
|
+
*/
|
|
307
|
+
function discoverTestFiles(baseDir = __dirname) {
|
|
308
|
+
const discovered = [];
|
|
309
|
+
|
|
310
|
+
if (!fs.existsSync(baseDir)) {
|
|
311
|
+
return discovered;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const files = fs.readdirSync(baseDir);
|
|
315
|
+
|
|
316
|
+
for (const file of files) {
|
|
317
|
+
// Look for test-*.js files
|
|
318
|
+
if (!file.startsWith('test-') || !file.endsWith('.js')) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Skip helper files
|
|
323
|
+
if (file === 'test-helper.js' || file === 'test-runner.js' || file === 'test-registry.js') {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const filePath = path.join(baseDir, file);
|
|
328
|
+
|
|
329
|
+
try {
|
|
330
|
+
// Try to load the test file and get its metadata
|
|
331
|
+
delete require.cache[require.resolve(filePath)];
|
|
332
|
+
const testModule = require(filePath);
|
|
333
|
+
|
|
334
|
+
if (testModule.metadata) {
|
|
335
|
+
// Test file exports metadata - use it
|
|
336
|
+
discovered.push({
|
|
337
|
+
file: file,
|
|
338
|
+
path: filePath,
|
|
339
|
+
metadata: testModule.metadata,
|
|
340
|
+
source: 'file'
|
|
341
|
+
});
|
|
342
|
+
} else {
|
|
343
|
+
// Test file doesn't export metadata yet - use static registry if available
|
|
344
|
+
// Find matching entry in static registry
|
|
345
|
+
for (const [type, metadata] of Object.entries(TEST_METADATA)) {
|
|
346
|
+
if (metadata.file === file) {
|
|
347
|
+
discovered.push({
|
|
348
|
+
file: file,
|
|
349
|
+
path: filePath,
|
|
350
|
+
metadata: {
|
|
351
|
+
name: type,
|
|
352
|
+
description: metadata.description,
|
|
353
|
+
requiredAbilities: metadata.requiredAbilities,
|
|
354
|
+
minDevices: metadata.minDevices
|
|
355
|
+
},
|
|
356
|
+
source: 'registry'
|
|
357
|
+
});
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
} catch (error) {
|
|
363
|
+
// File exists but couldn't be loaded - skip it
|
|
364
|
+
// This might happen if the file has syntax errors or missing dependencies
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return discovered;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Lists all tests with their metadata
|
|
374
|
+
* @returns {Object} Object mapping test types to their metadata
|
|
375
|
+
*/
|
|
376
|
+
function listTests() {
|
|
377
|
+
const tests = {};
|
|
378
|
+
|
|
379
|
+
for (const [type, metadata] of Object.entries(TEST_METADATA)) {
|
|
380
|
+
tests[type] = {
|
|
381
|
+
file: metadata.file,
|
|
382
|
+
description: metadata.description,
|
|
383
|
+
requiredAbilities: metadata.requiredAbilities,
|
|
384
|
+
minDevices: metadata.minDevices,
|
|
385
|
+
aliases: metadata.aliases || []
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return tests;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Validates that a test type exists
|
|
394
|
+
* @param {string} testType - Test type name or alias
|
|
395
|
+
* @returns {boolean} True if test type exists
|
|
396
|
+
*/
|
|
397
|
+
function testTypeExists(testType) {
|
|
398
|
+
return resolveTestType(testType) !== null;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
module.exports = {
|
|
402
|
+
// Core functions
|
|
403
|
+
getTestMetadata,
|
|
404
|
+
getAvailableTestTypes,
|
|
405
|
+
getTestDescription,
|
|
406
|
+
getRequiredAbilities,
|
|
407
|
+
getMinDevices,
|
|
408
|
+
getTestFile,
|
|
409
|
+
resolveTestType,
|
|
410
|
+
testTypeExists,
|
|
411
|
+
|
|
412
|
+
// Discovery
|
|
413
|
+
discoverTestFiles,
|
|
414
|
+
listTests,
|
|
415
|
+
|
|
416
|
+
// Direct access to metadata (for advanced use cases)
|
|
417
|
+
TEST_METADATA
|
|
418
|
+
};
|
|
419
|
+
|