@awarevue/agent-tester-cli 2.0.54
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/bin/agent-tester.js +3 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/app.module.d.ts +5 -0
- package/dist/app.module.js +36 -0
- package/dist/app.module.js.map +1 -0
- package/dist/cli-options.d.ts +12 -0
- package/dist/cli-options.js +5 -0
- package/dist/cli-options.js.map +1 -0
- package/dist/helpers/device-state-store.d.ts +19 -0
- package/dist/helpers/device-state-store.js +79 -0
- package/dist/helpers/device-state-store.js.map +1 -0
- package/dist/hub.service.d.ts +24 -0
- package/dist/hub.service.js +111 -0
- package/dist/hub.service.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +3 -0
- package/dist/loader.js +43 -0
- package/dist/loader.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +230 -0
- package/dist/main.js.map +1 -0
- package/dist/reporter.d.ts +11 -0
- package/dist/reporter.js +94 -0
- package/dist/reporter.js.map +1 -0
- package/dist/runner.service.d.ts +11 -0
- package/dist/runner.service.js +180 -0
- package/dist/runner.service.js.map +1 -0
- package/dist/scenario.types.d.ts +42 -0
- package/dist/scenario.types.js +14 -0
- package/dist/scenario.types.js.map +1 -0
- package/dist/scenarios/access/_utils.d.ts +6 -0
- package/dist/scenarios/access/_utils.js +52 -0
- package/dist/scenarios/access/_utils.js.map +1 -0
- package/dist/scenarios/access/communicates-bad-references.scenario.d.ts +3 -0
- package/dist/scenarios/access/communicates-bad-references.scenario.js +81 -0
- package/dist/scenarios/access/communicates-bad-references.scenario.js.map +1 -0
- package/dist/scenarios/access/communicates-not-found.scenario.d.ts +3 -0
- package/dist/scenarios/access/communicates-not-found.scenario.js +76 -0
- package/dist/scenarios/access/communicates-not-found.scenario.js.map +1 -0
- package/dist/scenarios/access/merges-access-objects.scenario.d.ts +3 -0
- package/dist/scenarios/access/merges-access-objects.scenario.js +187 -0
- package/dist/scenarios/access/merges-access-objects.scenario.js.map +1 -0
- package/dist/scenarios/access/people.scenario.d.ts +3 -0
- package/dist/scenarios/access/people.scenario.js +140 -0
- package/dist/scenarios/access/people.scenario.js.map +1 -0
- package/dist/scenarios/device-discovery.scenario.d.ts +3 -0
- package/dist/scenarios/device-discovery.scenario.js +43 -0
- package/dist/scenarios/device-discovery.scenario.js.map +1 -0
- package/dist/scenarios/doors/communicates-init-door-states.scenario.d.ts +3 -0
- package/dist/scenarios/doors/communicates-init-door-states.scenario.js +31 -0
- package/dist/scenarios/doors/communicates-init-door-states.scenario.js.map +1 -0
- package/dist/scenarios/doors/door-lock-unlock.scenario.d.ts +3 -0
- package/dist/scenarios/doors/door-lock-unlock.scenario.js +59 -0
- package/dist/scenarios/doors/door-lock-unlock.scenario.js.map +1 -0
- package/dist/scenarios/doors/door-release.scenario.d.ts +3 -0
- package/dist/scenarios/doors/door-release.scenario.js +52 -0
- package/dist/scenarios/doors/door-release.scenario.js.map +1 -0
- package/dist/scenarios/register.scenario.d.ts +3 -0
- package/dist/scenarios/register.scenario.js +32 -0
- package/dist/scenarios/register.scenario.js.map +1 -0
- package/dist/scenarios/start-stop.scenario.d.ts +3 -0
- package/dist/scenarios/start-stop.scenario.js +39 -0
- package/dist/scenarios/start-stop.scenario.js.map +1 -0
- package/dist/ws-server-transport.d.ts +17 -0
- package/dist/ws-server-transport.js +73 -0
- package/dist/ws-server-transport.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var AppModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.AppModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const hub_service_1 = require("./hub.service");
|
|
13
|
+
const runner_service_1 = require("./runner.service");
|
|
14
|
+
const cli_options_1 = require("./cli-options");
|
|
15
|
+
let AppModule = AppModule_1 = class AppModule {
|
|
16
|
+
static forRoot(options) {
|
|
17
|
+
return {
|
|
18
|
+
module: AppModule_1,
|
|
19
|
+
controllers: [],
|
|
20
|
+
providers: [
|
|
21
|
+
hub_service_1.HubService,
|
|
22
|
+
runner_service_1.RunnerService,
|
|
23
|
+
{
|
|
24
|
+
provide: cli_options_1.CLI_OPTIONS,
|
|
25
|
+
useValue: options,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
exports: [runner_service_1.RunnerService, hub_service_1.HubService],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
exports.AppModule = AppModule;
|
|
33
|
+
exports.AppModule = AppModule = AppModule_1 = __decorate([
|
|
34
|
+
(0, common_1.Module)({})
|
|
35
|
+
], AppModule);
|
|
36
|
+
//# sourceMappingURL=app.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,+CAA2C;AAC3C,qDAAiD;AACjD,+CAAwD;AAGjD,IAAM,SAAS,iBAAf,MAAM,SAAS;IACpB,MAAM,CAAC,OAAO,CAAC,OAAmB;QAChC,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,WAAW,EAAE,EAAE;YACf,SAAS,EAAE;gBACT,wBAAU;gBACV,8BAAa;gBACb;oBACE,OAAO,EAAE,yBAAW;oBACpB,QAAQ,EAAE,OAAO;iBAClB;aACF;YACD,OAAO,EAAE,CAAC,8BAAa,EAAE,wBAAU,CAAC;SACrC,CAAC;IACJ,CAAC;CACF,CAAA;AAhBY,8BAAS;oBAAT,SAAS;IADrB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,SAAS,CAgBrB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CLIOptions {
|
|
2
|
+
agentId: string;
|
|
3
|
+
tags: string[];
|
|
4
|
+
port: number;
|
|
5
|
+
timeout: number;
|
|
6
|
+
connectionTimeout: number;
|
|
7
|
+
report?: string;
|
|
8
|
+
providerConfig?: Record<string, unknown>;
|
|
9
|
+
verbose: boolean;
|
|
10
|
+
quiet: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const CLI_OPTIONS: unique symbol;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-options.js","sourceRoot":"","sources":["../src/cli-options.ts"],"names":[],"mappings":";;;AA6Ba,QAAA,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FromAgent, Message } from '@awarevue/api-types';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { DeviceState, DeviceStateStore } from '../scenario.types';
|
|
4
|
+
export declare class DeviceStateStoreImpl implements DeviceStateStore {
|
|
5
|
+
private readonly states;
|
|
6
|
+
private readonly changes$;
|
|
7
|
+
private readonly subscription;
|
|
8
|
+
private readonly defaultTimeoutMs;
|
|
9
|
+
constructor(messages$: Observable<Message<FromAgent>>, defaultTimeoutMs: number);
|
|
10
|
+
get(foreignRef: string): DeviceState | undefined;
|
|
11
|
+
getAll(): ReadonlyMap<string, DeviceState>;
|
|
12
|
+
has(foreignRef: string): boolean;
|
|
13
|
+
waitUntil(foreignRef: string, predicate: (state: DeviceState) => boolean, timeoutMs?: number): Promise<DeviceState>;
|
|
14
|
+
waitForChange(foreignRef: string, timeoutMs?: number): Promise<DeviceState>;
|
|
15
|
+
waitForDevices(foreignRefs: string[], predicate: (state: DeviceState) => boolean, timeoutMs?: number): Promise<Map<string, DeviceState>>;
|
|
16
|
+
assertState(foreignRef: string, predicate: (state: DeviceState) => boolean, message: string, timeoutMs?: number): Promise<void>;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
private reduce;
|
|
19
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeviceStateStoreImpl = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
class DeviceStateStoreImpl {
|
|
6
|
+
constructor(messages$, defaultTimeoutMs) {
|
|
7
|
+
this.states = new Map();
|
|
8
|
+
this.changes$ = new rxjs_1.Subject();
|
|
9
|
+
this.defaultTimeoutMs = defaultTimeoutMs;
|
|
10
|
+
this.subscription = messages$
|
|
11
|
+
.pipe((0, rxjs_1.filter)((msg) => msg.kind === 'state'))
|
|
12
|
+
.subscribe((msg) => {
|
|
13
|
+
if (msg.kind !== 'state')
|
|
14
|
+
return;
|
|
15
|
+
this.reduce(msg.foreignRef, msg.mergeProps, msg.removeProps);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
get(foreignRef) {
|
|
19
|
+
const state = this.states.get(foreignRef);
|
|
20
|
+
return state ? { ...state } : undefined;
|
|
21
|
+
}
|
|
22
|
+
getAll() {
|
|
23
|
+
return this.states;
|
|
24
|
+
}
|
|
25
|
+
has(foreignRef) {
|
|
26
|
+
return this.states.has(foreignRef);
|
|
27
|
+
}
|
|
28
|
+
async waitUntil(foreignRef, predicate, timeoutMs) {
|
|
29
|
+
const current = this.states.get(foreignRef);
|
|
30
|
+
if (current && predicate(current)) {
|
|
31
|
+
return { ...current };
|
|
32
|
+
}
|
|
33
|
+
return (0, rxjs_1.firstValueFrom)(this.changes$.pipe((0, rxjs_1.filter)((c) => c.foreignRef === foreignRef), (0, rxjs_1.map)((c) => c.state), (0, rxjs_1.filter)((state) => predicate(state)), (0, rxjs_1.map)((state) => ({ ...state })), (0, rxjs_1.take)(1), (0, rxjs_1.timeout)(timeoutMs ?? this.defaultTimeoutMs)));
|
|
34
|
+
}
|
|
35
|
+
async waitForChange(foreignRef, timeoutMs) {
|
|
36
|
+
return (0, rxjs_1.firstValueFrom)(this.changes$.pipe((0, rxjs_1.filter)((c) => c.foreignRef === foreignRef), (0, rxjs_1.map)((c) => ({ ...c.state })), (0, rxjs_1.take)(1), (0, rxjs_1.timeout)(timeoutMs ?? this.defaultTimeoutMs)));
|
|
37
|
+
}
|
|
38
|
+
async waitForDevices(foreignRefs, predicate, timeoutMs) {
|
|
39
|
+
const effectiveTimeout = timeoutMs ?? this.defaultTimeoutMs;
|
|
40
|
+
const result = new Map();
|
|
41
|
+
const deadline = Date.now() + effectiveTimeout;
|
|
42
|
+
await Promise.all(foreignRefs.map(async (ref) => {
|
|
43
|
+
const remaining = deadline - Date.now();
|
|
44
|
+
if (remaining <= 0) {
|
|
45
|
+
throw new Error(`waitForDevices: timed out before checking device '${ref}'`);
|
|
46
|
+
}
|
|
47
|
+
const state = await this.waitUntil(ref, predicate, remaining);
|
|
48
|
+
result.set(ref, state);
|
|
49
|
+
}));
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
async assertState(foreignRef, predicate, message, timeoutMs) {
|
|
53
|
+
try {
|
|
54
|
+
await this.waitUntil(foreignRef, predicate, timeoutMs);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
const current = this.states.get(foreignRef);
|
|
58
|
+
const stateDesc = current
|
|
59
|
+
? JSON.stringify(current, null, 2)
|
|
60
|
+
: 'no state received';
|
|
61
|
+
throw new Error(`${message} — device '${foreignRef}' current state: ${stateDesc}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
dispose() {
|
|
65
|
+
this.subscription.unsubscribe();
|
|
66
|
+
this.changes$.complete();
|
|
67
|
+
}
|
|
68
|
+
reduce(foreignRef, mergeProps, removeProps) {
|
|
69
|
+
let state = this.states.get(foreignRef) ?? {};
|
|
70
|
+
state = { ...state, ...mergeProps };
|
|
71
|
+
for (const key of removeProps) {
|
|
72
|
+
delete state[key];
|
|
73
|
+
}
|
|
74
|
+
this.states.set(foreignRef, state);
|
|
75
|
+
this.changes$.next({ foreignRef, state: { ...state } });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.DeviceStateStoreImpl = DeviceStateStoreImpl;
|
|
79
|
+
//# sourceMappingURL=device-state-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-state-store.js","sourceRoot":"","sources":["../../src/helpers/device-state-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { OnModuleInit, OnModuleDestroy } from "@nestjs/common";
|
|
2
|
+
import { HttpAdapterHost } from "@nestjs/core";
|
|
3
|
+
import { Message, RegisterRq } from "@awarevue/api-types";
|
|
4
|
+
import { AgentProtocol } from "@awarevue/agent-sdk";
|
|
5
|
+
import { CLIOptions } from "./cli-options";
|
|
6
|
+
export interface ConnectedAgent {
|
|
7
|
+
protocol: AgentProtocol<"server">;
|
|
8
|
+
registerPayload: Message<RegisterRq>;
|
|
9
|
+
peerId: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class HubService implements OnModuleInit, OnModuleDestroy {
|
|
12
|
+
private readonly httpAdapterHost;
|
|
13
|
+
private readonly options;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
private wss;
|
|
16
|
+
private readonly hub;
|
|
17
|
+
private peerCounter;
|
|
18
|
+
constructor(httpAdapterHost: HttpAdapterHost, options: CLIOptions);
|
|
19
|
+
onModuleDestroy(): void;
|
|
20
|
+
onModuleInit(): void;
|
|
21
|
+
awaitAgent(agentId: string, timeoutMs: number): Promise<ConnectedAgent>;
|
|
22
|
+
private handleRegistration;
|
|
23
|
+
close(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var HubService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.HubService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const core_1 = require("@nestjs/core");
|
|
19
|
+
const ws_1 = require("ws");
|
|
20
|
+
const api_types_1 = require("@awarevue/api-types");
|
|
21
|
+
const agent_sdk_1 = require("@awarevue/agent-sdk");
|
|
22
|
+
const ws_server_transport_1 = require("./ws-server-transport");
|
|
23
|
+
const cli_options_1 = require("./cli-options");
|
|
24
|
+
let HubService = HubService_1 = class HubService {
|
|
25
|
+
constructor(httpAdapterHost, options) {
|
|
26
|
+
this.httpAdapterHost = httpAdapterHost;
|
|
27
|
+
this.options = options;
|
|
28
|
+
this.logger = new common_1.Logger(HubService_1.name);
|
|
29
|
+
this.hub = new agent_sdk_1.InMemoryHub();
|
|
30
|
+
this.peerCounter = 0;
|
|
31
|
+
}
|
|
32
|
+
onModuleDestroy() {
|
|
33
|
+
this.close();
|
|
34
|
+
}
|
|
35
|
+
onModuleInit() {
|
|
36
|
+
const server = this.httpAdapterHost.httpAdapter.getHttpServer();
|
|
37
|
+
this.wss = new ws_1.WebSocketServer({ server });
|
|
38
|
+
this.wss.on("connection", (ws) => {
|
|
39
|
+
const peerId = `peer-${++this.peerCounter}`;
|
|
40
|
+
this.logger.log(`WebSocket peer connected: ${peerId}`);
|
|
41
|
+
const transport = new ws_server_transport_1.WsServerDuplexTransport(ws);
|
|
42
|
+
this.hub.addPeer(peerId, transport);
|
|
43
|
+
});
|
|
44
|
+
this.hub.peerEvents$.subscribe((event) => {
|
|
45
|
+
if (event.type === "leave") {
|
|
46
|
+
this.logger.log(`Peer disconnected: ${event.peer}`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async awaitAgent(agentId, timeoutMs) {
|
|
51
|
+
this.logger.log(`Waiting for agent '${agentId}' to connect (timeout: ${timeoutMs}ms)...`);
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const timer = setTimeout(() => {
|
|
54
|
+
reject(new Error(`Timed out after ${timeoutMs}ms waiting for agent '${agentId}' to connect and register`));
|
|
55
|
+
sub.unsubscribe();
|
|
56
|
+
}, timeoutMs);
|
|
57
|
+
const sub = this.hub.messages$.subscribe(({ peer, msg }) => {
|
|
58
|
+
if (msg.kind !== "register")
|
|
59
|
+
return;
|
|
60
|
+
if (msg.from !== agentId) {
|
|
61
|
+
this.logger.warn(`Received register from '${msg.from}', expected '${agentId}' — ignoring`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
sub.unsubscribe();
|
|
66
|
+
try {
|
|
67
|
+
resolve(this.handleRegistration(peer, msg, agentId));
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
reject(err);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
handleRegistration(peer, msg, agentId) {
|
|
76
|
+
const issues = (0, api_types_1.getAgentMessageIssues)(msg);
|
|
77
|
+
if (issues.length > 0) {
|
|
78
|
+
throw new Error(`Invalid register from ${peer}: ${issues.join(", ")}`);
|
|
79
|
+
}
|
|
80
|
+
const registerMsg = msg;
|
|
81
|
+
const conn = this.hub.connection(peer);
|
|
82
|
+
if (!conn) {
|
|
83
|
+
throw new Error(`Peer ${peer} disconnected before registration`);
|
|
84
|
+
}
|
|
85
|
+
const protocol = new agent_sdk_1.AgentProtocol(conn, {
|
|
86
|
+
id: "test-hub",
|
|
87
|
+
replyTimeout: this.options.timeout,
|
|
88
|
+
});
|
|
89
|
+
protocol.send({
|
|
90
|
+
kind: "register-rs",
|
|
91
|
+
requestId: registerMsg.id,
|
|
92
|
+
});
|
|
93
|
+
this.logger.debug(`Agent '${agentId}' registered (peer: ${peer}, providers: ${Object.keys(registerMsg.providers).join(", ")})`);
|
|
94
|
+
return {
|
|
95
|
+
protocol,
|
|
96
|
+
registerPayload: registerMsg,
|
|
97
|
+
peerId: peer,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
close() {
|
|
101
|
+
this.hub.close();
|
|
102
|
+
this.wss?.close();
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
exports.HubService = HubService;
|
|
106
|
+
exports.HubService = HubService = HubService_1 = __decorate([
|
|
107
|
+
(0, common_1.Injectable)(),
|
|
108
|
+
__param(1, (0, common_1.Inject)(cli_options_1.CLI_OPTIONS)),
|
|
109
|
+
__metadata("design:paramtypes", [core_1.HttpAdapterHost, Object])
|
|
110
|
+
], HubService);
|
|
111
|
+
//# sourceMappingURL=hub.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.service.js","sourceRoot":"","sources":["../src/hub.service.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeviceStateStoreImpl = exports.scenarioFail = exports.scenarioPass = exports.filterScenarios = exports.loadScenarios = void 0;
|
|
4
|
+
var loader_1 = require("./loader");
|
|
5
|
+
Object.defineProperty(exports, "loadScenarios", { enumerable: true, get: function () { return loader_1.loadScenarios; } });
|
|
6
|
+
Object.defineProperty(exports, "filterScenarios", { enumerable: true, get: function () { return loader_1.filterScenarios; } });
|
|
7
|
+
var scenario_types_1 = require("./scenario.types");
|
|
8
|
+
Object.defineProperty(exports, "scenarioPass", { enumerable: true, get: function () { return scenario_types_1.scenarioPass; } });
|
|
9
|
+
Object.defineProperty(exports, "scenarioFail", { enumerable: true, get: function () { return scenario_types_1.scenarioFail; } });
|
|
10
|
+
var device_state_store_1 = require("./helpers/device-state-store");
|
|
11
|
+
Object.defineProperty(exports, "DeviceStateStoreImpl", { enumerable: true, get: function () { return device_state_store_1.DeviceStateStoreImpl; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA0D;AAAjD,uGAAA,aAAa,OAAA;AAAE,yGAAA,eAAe,OAAA;AACvC,mDAQ0B;AAFxB,8GAAA,YAAY,OAAA;AACZ,8GAAA,YAAY,OAAA;AAEd,mEAAoE;AAA3D,0HAAA,oBAAoB,OAAA"}
|
package/dist/loader.d.ts
ADDED
package/dist/loader.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadScenarios = loadScenarios;
|
|
4
|
+
exports.filterScenarios = filterScenarios;
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
function findFilesRecursive(dir, pattern) {
|
|
8
|
+
const results = [];
|
|
9
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
10
|
+
const fullPath = path.join(dir, entry.name);
|
|
11
|
+
if (entry.isDirectory()) {
|
|
12
|
+
results.push(...findFilesRecursive(fullPath, pattern));
|
|
13
|
+
}
|
|
14
|
+
else if (pattern.test(entry.name)) {
|
|
15
|
+
results.push(fullPath);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
function loadScenarios() {
|
|
21
|
+
const scenariosDir = path.join(__dirname, "scenarios");
|
|
22
|
+
const files = findFilesRecursive(scenariosDir, /\.scenario\.(ts|js)$/);
|
|
23
|
+
const scenarios = [];
|
|
24
|
+
for (const fullPath of files) {
|
|
25
|
+
const mod = require(fullPath);
|
|
26
|
+
const scenario = mod.default ?? mod;
|
|
27
|
+
if (!scenario.name || !scenario.run) {
|
|
28
|
+
const relPath = path.relative(scenariosDir, fullPath);
|
|
29
|
+
console.warn(`⚠ Skipping ${relPath}: missing 'name' or 'run' export`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
scenarios.push(scenario);
|
|
33
|
+
}
|
|
34
|
+
scenarios.sort((a, b) => a.name.localeCompare(b.name));
|
|
35
|
+
return scenarios;
|
|
36
|
+
}
|
|
37
|
+
function filterScenarios(scenarios, tags) {
|
|
38
|
+
if (tags.length === 0)
|
|
39
|
+
return scenarios;
|
|
40
|
+
const tagSet = new Set(tags.map((t) => t.toLowerCase()));
|
|
41
|
+
return scenarios.filter((s) => s.tags.some((t) => tagSet.has(t.toLowerCase())));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":";;AAwBA,sCAwBC;AAMD,0CASC;AA/DD,6BAA6B;AAC7B,yBAAyB;AAMzB,SAAS,kBAAkB,CAAC,GAAW,EAAE,OAAe;IACtD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAMD,SAAgB,aAAa;IAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,kBAAkB,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAC;IAEvE,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;QAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAa,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAE9C,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,cAAc,OAAO,kCAAkC,CAAC,CAAC;YACtE,SAAS;QACX,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAGD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEvD,OAAO,SAAS,CAAC;AACnB,CAAC;AAMD,SAAgB,eAAe,CAC7B,SAAqB,EACrB,IAAc;IAEd,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACzD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAChD,CAAC;AACJ,CAAC"}
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@nestjs/core");
|
|
4
|
+
const yargs = require("yargs");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const app_module_1 = require("./app.module");
|
|
8
|
+
const runner_service_1 = require("./runner.service");
|
|
9
|
+
const loader_1 = require("./loader");
|
|
10
|
+
const RESET = "\x1b[0m";
|
|
11
|
+
const BOLD = "\x1b[1m";
|
|
12
|
+
const DIM = "\x1b[2m";
|
|
13
|
+
const CYAN = "\x1b[36m";
|
|
14
|
+
const RED = "\x1b[31m";
|
|
15
|
+
function getVersion() {
|
|
16
|
+
try {
|
|
17
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf-8"));
|
|
18
|
+
return pkg.version ?? "unknown";
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return "unknown";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function printBanner(version) {
|
|
25
|
+
console.log();
|
|
26
|
+
console.log(`${BOLD}${CYAN} agent-tester${RESET} ${DIM}v${version}${RESET}`);
|
|
27
|
+
console.log(`${DIM} Aware Agent Protocol Conformance Test Runner${RESET}`);
|
|
28
|
+
console.log();
|
|
29
|
+
}
|
|
30
|
+
function printScenarioList(tags) {
|
|
31
|
+
const all = (0, loader_1.loadScenarios)();
|
|
32
|
+
const filtered = (0, loader_1.filterScenarios)(all, tags);
|
|
33
|
+
console.log(`${BOLD}Available scenarios${RESET} (${filtered.length}/${all.length}):`);
|
|
34
|
+
console.log();
|
|
35
|
+
for (const s of filtered) {
|
|
36
|
+
const tagStr = s.tags.length > 0 ? ` ${DIM}[${s.tags.join(", ")}]${RESET}` : "";
|
|
37
|
+
console.log(` ${CYAN}•${RESET} ${s.name}${tagStr}`);
|
|
38
|
+
if (s.description) {
|
|
39
|
+
console.log(` ${DIM}${s.description}${RESET}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
console.log();
|
|
43
|
+
if (tags.length > 0) {
|
|
44
|
+
console.log(`${DIM}Filtered by tags: ${tags.join(", ")}${RESET}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function main() {
|
|
48
|
+
const argv = await yargs
|
|
49
|
+
.scriptName("agent-tester")
|
|
50
|
+
.usage("$0 --agentId <id> [options]")
|
|
51
|
+
.usage("")
|
|
52
|
+
.usage("Run the Aware agent protocol conformance test suite against a real agent.")
|
|
53
|
+
.usage("The hub starts a WebSocket server, waits for the agent to connect,")
|
|
54
|
+
.usage("then exercises it through a battery of scenarios.")
|
|
55
|
+
.option("agentId", {
|
|
56
|
+
type: "string",
|
|
57
|
+
describe: "Agent ID to expect a connection from",
|
|
58
|
+
group: "Required:",
|
|
59
|
+
})
|
|
60
|
+
.option("tags", {
|
|
61
|
+
type: "string",
|
|
62
|
+
default: "",
|
|
63
|
+
describe: "Comma-separated tags to filter scenarios (e.g. core,doors)",
|
|
64
|
+
group: "Filtering:",
|
|
65
|
+
})
|
|
66
|
+
.option("port", {
|
|
67
|
+
type: "number",
|
|
68
|
+
default: 3005,
|
|
69
|
+
describe: "Port to listen on for WebSocket connections",
|
|
70
|
+
group: "Connection:",
|
|
71
|
+
})
|
|
72
|
+
.option("timeout", {
|
|
73
|
+
type: "number",
|
|
74
|
+
default: 30000,
|
|
75
|
+
describe: "Per-scenario timeout in milliseconds",
|
|
76
|
+
group: "Connection:",
|
|
77
|
+
})
|
|
78
|
+
.option("connectionTimeout", {
|
|
79
|
+
type: "number",
|
|
80
|
+
default: 30000,
|
|
81
|
+
describe: "How long to wait for agent to connect (ms)",
|
|
82
|
+
group: "Connection:",
|
|
83
|
+
})
|
|
84
|
+
.option("report", {
|
|
85
|
+
type: "string",
|
|
86
|
+
describe: "Path to write JUnit XML report (for CI integration)",
|
|
87
|
+
group: "Output:",
|
|
88
|
+
})
|
|
89
|
+
.option("config", {
|
|
90
|
+
type: "string",
|
|
91
|
+
describe: "Path to a JSON file with provider config",
|
|
92
|
+
group: "Configuration:",
|
|
93
|
+
})
|
|
94
|
+
.option("list", {
|
|
95
|
+
type: "boolean",
|
|
96
|
+
default: false,
|
|
97
|
+
describe: "List available scenarios and exit (does not require --agentId)",
|
|
98
|
+
group: "Output:",
|
|
99
|
+
})
|
|
100
|
+
.option("verbose", {
|
|
101
|
+
type: "boolean",
|
|
102
|
+
default: false,
|
|
103
|
+
describe: "Show detailed internal logs (NestJS, protocol messages)",
|
|
104
|
+
group: "Output:",
|
|
105
|
+
})
|
|
106
|
+
.option("quiet", {
|
|
107
|
+
type: "boolean",
|
|
108
|
+
default: false,
|
|
109
|
+
describe: "Suppress all output except the final summary and errors",
|
|
110
|
+
group: "Output:",
|
|
111
|
+
})
|
|
112
|
+
.check((argv) => {
|
|
113
|
+
if (argv.verbose && argv.quiet) {
|
|
114
|
+
throw new Error("--verbose and --quiet cannot be used together");
|
|
115
|
+
}
|
|
116
|
+
if (!argv.list && !argv.agentId) {
|
|
117
|
+
throw new Error("--agentId is required (unless using --list)");
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
})
|
|
121
|
+
.example("$0 --agentId my-agent", 'Run all scenarios against "my-agent"')
|
|
122
|
+
.example("$0 --agentId my-agent --tags core --report results.xml", "Run core scenarios, write JUnit report")
|
|
123
|
+
.example("$0 --agentId my-agent --quiet --report junit.xml", "CI mode")
|
|
124
|
+
.example("$0 --list", "Print all available scenarios")
|
|
125
|
+
.example("$0 --list --tags doors", 'Print scenarios tagged "doors"')
|
|
126
|
+
.epilogue("Exit codes:\n" +
|
|
127
|
+
" 0 All scenarios passed\n" +
|
|
128
|
+
" 1 One or more scenarios failed (or connection error)\n" +
|
|
129
|
+
" 2 Invalid arguments or configuration error")
|
|
130
|
+
.strict()
|
|
131
|
+
.help()
|
|
132
|
+
.version(getVersion())
|
|
133
|
+
.wrap(Math.min(100, yargs.terminalWidth()))
|
|
134
|
+
.parse();
|
|
135
|
+
const version = getVersion();
|
|
136
|
+
const quiet = argv.quiet;
|
|
137
|
+
if (argv.list) {
|
|
138
|
+
const tags = argv.tags
|
|
139
|
+
? argv.tags
|
|
140
|
+
.split(",")
|
|
141
|
+
.map((t) => t.trim())
|
|
142
|
+
.filter(Boolean)
|
|
143
|
+
: [];
|
|
144
|
+
printBanner(version);
|
|
145
|
+
printScenarioList(tags);
|
|
146
|
+
process.exit(0);
|
|
147
|
+
}
|
|
148
|
+
if (!quiet) {
|
|
149
|
+
printBanner(version);
|
|
150
|
+
}
|
|
151
|
+
let providerConfig;
|
|
152
|
+
if (argv.config) {
|
|
153
|
+
const configPath = path.resolve(argv.config);
|
|
154
|
+
if (!fs.existsSync(configPath)) {
|
|
155
|
+
console.error(`${RED}Error:${RESET} Config file not found: ${configPath}`);
|
|
156
|
+
process.exit(2);
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const raw = fs.readFileSync(configPath, "utf-8");
|
|
160
|
+
providerConfig = JSON.parse(raw);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
console.error(`${RED}Error:${RESET} Failed to parse config file: ${err.message}`);
|
|
164
|
+
process.exit(2);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const options = {
|
|
168
|
+
agentId: argv.agentId,
|
|
169
|
+
tags: argv.tags
|
|
170
|
+
? argv.tags
|
|
171
|
+
.split(",")
|
|
172
|
+
.map((t) => t.trim())
|
|
173
|
+
.filter(Boolean)
|
|
174
|
+
: [],
|
|
175
|
+
port: argv.port,
|
|
176
|
+
timeout: argv.timeout,
|
|
177
|
+
connectionTimeout: argv.connectionTimeout,
|
|
178
|
+
report: argv.report,
|
|
179
|
+
providerConfig,
|
|
180
|
+
verbose: argv.verbose,
|
|
181
|
+
quiet,
|
|
182
|
+
};
|
|
183
|
+
const nestLogLevels = argv.verbose
|
|
184
|
+
? ["error", "warn", "log", "debug", "verbose"]
|
|
185
|
+
: quiet
|
|
186
|
+
? ["error"]
|
|
187
|
+
: ["error", "warn"];
|
|
188
|
+
const app = await core_1.NestFactory.create(app_module_1.AppModule.forRoot(options), {
|
|
189
|
+
logger: nestLogLevels,
|
|
190
|
+
});
|
|
191
|
+
let shuttingDown = false;
|
|
192
|
+
const shutdown = async (signal) => {
|
|
193
|
+
if (shuttingDown)
|
|
194
|
+
return;
|
|
195
|
+
shuttingDown = true;
|
|
196
|
+
if (!quiet) {
|
|
197
|
+
console.log(`\n${DIM}Received ${signal}, shutting down...${RESET}`);
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
await app.close();
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
}
|
|
204
|
+
process.exit(1);
|
|
205
|
+
};
|
|
206
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
207
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
208
|
+
await app.listen(options.port);
|
|
209
|
+
if (!quiet) {
|
|
210
|
+
console.log(`${DIM} Listening on port ${RESET}${BOLD}${options.port}${RESET}` +
|
|
211
|
+
`${DIM} · Timeout ${options.timeout}ms · Connection timeout ${options.connectionTimeout}ms${RESET}`);
|
|
212
|
+
if (options.tags.length > 0) {
|
|
213
|
+
console.log(`${DIM} Tags: ${options.tags.join(", ")}${RESET}`);
|
|
214
|
+
}
|
|
215
|
+
console.log();
|
|
216
|
+
}
|
|
217
|
+
const runner = app.get(runner_service_1.RunnerService);
|
|
218
|
+
const exitCode = await runner.run();
|
|
219
|
+
try {
|
|
220
|
+
await app.close();
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
}
|
|
224
|
+
process.exit(exitCode);
|
|
225
|
+
}
|
|
226
|
+
main().catch((err) => {
|
|
227
|
+
console.error(`${RED}Fatal:${RESET} ${err.message}`);
|
|
228
|
+
process.exit(2);
|
|
229
|
+
});
|
|
230
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|