main
html 188 lines 7.17 KB
Raw
1 <html>
2 <head>
3 <title>WebSocket Test Harness</title>
4 <script type="module">
5 import { store as websocketTesterStore } from "/components/settings/developer/websocket-test-store.js";
6 </script>
7 </head>
8 <body>
9 <div x-data>
10 <template x-if="window.runtimeInfo?.isDevelopment && $store.websocketTesterStore">
11 <div class="ws-tester" x-create="$store.websocketTesterStore.onOpen()" x-destroy="$store.websocketTesterStore.detach()">
12 <h2>WebSocket Developer Harness</h2>
13 <p class="ws-description">
14 Run automated and manual validations for the WebSocket client. Automatic tests cover fire-and-forget emit, request/response, timeout handling, subscription persistence, and requestAll aggregation.
15 </p>
16
17 <div class="ws-section">
18 <div class="ws-section-header">
19 <h3>Automatic Validation Suite</h3>
20 <button class="btn btn-ok" :disabled="$store.websocketTesterStore.running" @click="$store.websocketTesterStore.runAutomaticSuite()">
21 <span x-show="!$store.websocketTesterStore.running">Run Full Suite</span>
22 <span x-show="$store.websocketTesterStore.running">Running...</span>
23 </button>
24 </div>
25 <p class="ws-section-info">
26 Executes all WebSocket feature tests sequentially. Progress and results appear in the log below and via toasts (5s).
27 </p>
28 </div>
29
30 <div class="ws-section">
31 <div class="ws-section-header">
32 <h3>Manual Tests</h3>
33 <div class="ws-button-grid">
34 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualEmit()">Fire-and-forget emit</button>
35 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualRequest()">Request/Response</button>
36 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualRequestTimeout()">Request timeout</button>
37 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualPersistence()">Subscription persistence</button>
38 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualRequestAll()">requestAll aggregation</button>
39 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualStateSync()">State sync (no poll when healthy)</button>
40 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualContextSwitch()">Context switching</button>
41 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualFallbackRecovery()">Fallback + recovery (DEGRADED)</button>
42 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.runManualResyncTriggers()">Resync triggers (runtime_epoch/seq gap)</button>
43 <button class="btn" :disabled="$store.websocketTesterStore.manualRunning" @click="$store.websocketTesterStore.triggerBroadcastDemo()">Broadcast demo</button>
44 </div>
45 <p class="ws-section-info">
46 Manual tests trigger individual scenarios and show toast results. Open a second browser tab for requestAll/broadcast demos to observe multi-connection behaviour.
47 </p>
48 </div>
49 </div>
50
51 <div class="ws-section">
52 <div class="ws-section-header">
53 <h3>Log Output</h3>
54 <div class="ws-log-actions">
55 <button class="btn slim" @click="$store.websocketTesterStore.clearLog()">Clear</button>
56 </div>
57 </div>
58 <textarea class="ws-log" readonly x-model="$store.websocketTesterStore.logs"></textarea>
59 </div>
60
61 <div class="ws-section" x-show="$store.websocketTesterStore.lastAggregated">
62 <div class="ws-section-header">
63 <h3>Last Aggregated Results</h3>
64 </div>
65 <pre class="ws-json" x-text="JSON.stringify($store.websocketTesterStore.lastAggregated, null, 2)"></pre>
66 </div>
67
68 <div class="ws-section" x-show="$store.websocketTesterStore.receivedBroadcasts.length">
69 <div class="ws-section-header">
70 <h3>Recent Broadcast Payloads</h3>
71 </div>
72 <ul class="ws-list">
73 <template x-for="item in $store.websocketTesterStore.receivedBroadcasts.slice(-10)" :key="item.id || (item.timestamp + item.eventType)">
74 <li><strong x-text="item.eventType"></strong>: <span x-text="JSON.stringify(item.payload)"></span> <em x-text="item.timestamp"></em></li>
75 </template>
76 </ul>
77 </div>
78 </div>
79 </template>
80 <template x-if="!window.runtimeInfo?.isDevelopment">
81 <div class="ws-tester ws-disabled">
82 <h2>WebSocket Developer Harness</h2>
83 <p class="ws-description">
84 The WebSocket test harness is available only when Agent Zero runs in development mode.
85 </p>
86 </div>
87 </template>
88 </div>
89
90 <style>
91 .ws-tester {
92 display: flex;
93 flex-direction: column;
94 gap: 1.5rem;
95 color: var(--color-text-primary);
96 }
97
98 .ws-description {
99 margin: 0;
100 color: var(--color-text-secondary);
101 }
102
103 .ws-disabled {
104 align-items: flex-start;
105 }
106
107 .ws-section {
108 background: var(--color-bg-secondary);
109 border: 1px solid var(--color-border);
110 border-radius: 6px;
111 padding: 1rem;
112 }
113
114 .ws-section-header {
115 display: flex;
116 align-items: center;
117 justify-content: space-between;
118 gap: 1rem;
119 margin-bottom: 0.5rem;
120 }
121
122 .ws-section-header h3 {
123 margin: 0;
124 font-size: 1.1rem;
125 }
126
127 .ws-section-info {
128 margin: 0;
129 color: var(--color-text-secondary);
130 font-size: 0.9rem;
131 }
132
133 .ws-button-grid {
134 display: grid;
135 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
136 gap: 0.5rem;
137 margin: 1rem 0;
138 }
139
140 .ws-log {
141 width: 100%;
142 min-height: 12em;
143 background: var(--color-bg-primary);
144 color: var(--color-text-primary);
145 border: 1px solid var(--color-border);
146 border-radius: 4px;
147 padding: 0.75rem;
148 font-family: monospace;
149 font-size: 0.85rem;
150 resize: vertical;
151 }
152
153 .ws-log-actions {
154 display: flex;
155 gap: 0.5rem;
156 align-items: center;
157 }
158
159 .ws-json {
160 background: var(--color-bg-primary);
161 border: 1px solid var(--color-border);
162 border-radius: 4px;
163 padding: 0.75rem;
164 font-family: monospace;
165 font-size: 0.85rem;
166 overflow: auto;
167 max-height: 200px;
168 }
169
170 .ws-list {
171 list-style: none;
172 padding: 0;
173 margin: 0;
174 display: flex;
175 flex-direction: column;
176 gap: 0.5rem;
177 font-size: 0.9rem;
178 }
179
180 .ws-list li {
181 background: var(--color-bg-primary);
182 border: 1px solid var(--color-border);
183 border-radius: 4px;
184 padding: 0.5rem;
185 }
186 </style>
187 </body>
188 </html>