Skip to content

Commit 28acb25

Browse files
authored
Merge branch 'main' into feat/new-tools
2 parents 66c7991 + 145fb6e commit 28acb25

1 file changed

Lines changed: 141 additions & 1 deletion

File tree

moq-test-ui/public/js/app.js

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ import { HistoryUI } from './history-ui.js';
77

88
class App {
99
constructor() {
10+
this.endpointCookieName = 'moq_test_ui_endpoint_url';
11+
this.endpointQueryValue = null;
12+
this.autoRunRequested = false;
13+
this.defaultEndpointUrl = '';
14+
this.autoRunSelfTestStarted = false;
15+
this.boundRelayInputIds = new Set();
16+
17+
this.initEndpointDefaults();
18+
1019
this.tools = [];
1120
this.selectedTool = null;
1221
this.currentRunId = null;
@@ -37,6 +46,124 @@ class App {
3746
this.ws.connect();
3847
}
3948

49+
initEndpointDefaults() {
50+
const query = new URLSearchParams(window.location.search);
51+
const endpoint =
52+
query.get('endpoint') ||
53+
query.get('endpoint_url') ||
54+
query.get('endpointUrl') ||
55+
query.get('relay_url') ||
56+
query.get('relayUrl') ||
57+
'';
58+
59+
const autoRunRaw = query.get('auto_run') || query.get('autorun') || query.get('autoRun') || '';
60+
61+
this.endpointQueryValue = endpoint.trim();
62+
this.autoRunRequested = this.parseBooleanFlag(autoRunRaw);
63+
64+
if (this.autoRunRequested && !this.endpointQueryValue) {
65+
console.warn('Ignoring auto-run because no endpoint URL was provided in query parameters.');
66+
this.autoRunRequested = false;
67+
}
68+
69+
const cookieEndpoint = this.getCookie(this.endpointCookieName).trim();
70+
this.defaultEndpointUrl = this.endpointQueryValue || cookieEndpoint;
71+
if (this.endpointQueryValue) {
72+
this.setEndpointUrl(this.endpointQueryValue);
73+
}
74+
}
75+
76+
parseBooleanFlag(value) {
77+
const normalized = String(value || '').trim().toLowerCase();
78+
return ['1', 'true', 'yes', 'y', 'on'].includes(normalized);
79+
}
80+
81+
getCookie(name) {
82+
const prefix = `${name}=`;
83+
const parts = document.cookie ? document.cookie.split(';') : [];
84+
for (const part of parts) {
85+
const trimmed = part.trim();
86+
if (trimmed.startsWith(prefix)) {
87+
return decodeURIComponent(trimmed.slice(prefix.length));
88+
}
89+
}
90+
return '';
91+
}
92+
93+
setCookie(name, value, days = 365) {
94+
const expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString();
95+
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; SameSite=Lax`;
96+
}
97+
98+
setEndpointUrl(url) {
99+
const trimmed = (url || '').trim();
100+
if (!trimmed) return;
101+
this.defaultEndpointUrl = trimmed;
102+
this.setCookie(this.endpointCookieName, trimmed);
103+
this.applyEndpointToRelayInputs(trimmed);
104+
}
105+
106+
isRelayParam(param) {
107+
if (!param) return false;
108+
const id = String(param.id || '').toLowerCase();
109+
const label = String(param.label || '').toLowerCase();
110+
return id === 'relay_url' || id === 'endpoint_url' || label.includes('relay url');
111+
}
112+
113+
applyEndpointToRelayInputs(url) {
114+
const value = (url || '').trim();
115+
if (!value) return;
116+
117+
const selfTestRelay = document.getElementById('st-relay-url');
118+
if (selfTestRelay) {
119+
selfTestRelay.value = value;
120+
}
121+
122+
if (!Array.isArray(this.paramForm?.params) || this.paramForm.params.length === 0) return;
123+
for (const param of this.paramForm.params) {
124+
if (!this.isRelayParam(param)) continue;
125+
const input = document.getElementById(`param-${param.id}`);
126+
if (input) {
127+
input.value = value;
128+
}
129+
}
130+
}
131+
132+
bindRelayInputSync() {
133+
const selfTestRelay = document.getElementById('st-relay-url');
134+
if (selfTestRelay && !this.boundRelayInputIds.has('st-relay-url')) {
135+
selfTestRelay.addEventListener('change', () => {
136+
const value = selfTestRelay.value.trim();
137+
if (value) {
138+
this.setEndpointUrl(value);
139+
}
140+
});
141+
this.boundRelayInputIds.add('st-relay-url');
142+
}
143+
144+
if (!Array.isArray(this.paramForm?.params)) return;
145+
for (const param of this.paramForm.params) {
146+
if (!this.isRelayParam(param)) continue;
147+
const input = document.getElementById(`param-${param.id}`);
148+
if (!input) continue;
149+
if (this.boundRelayInputIds.has(input.id)) continue;
150+
input.addEventListener('change', () => {
151+
const value = input.value.trim();
152+
if (value) {
153+
this.setEndpointUrl(value);
154+
}
155+
});
156+
this.boundRelayInputIds.add(input.id);
157+
}
158+
}
159+
160+
maybeAutoRunSelfTest() {
161+
if (!this.autoRunRequested || this.autoRunSelfTestStarted) return;
162+
this.autoRunSelfTestStarted = true;
163+
this.switchView('self-test');
164+
this.startSelfTest();
165+
}
166+
40167
bindUI() {
41168
// Navigation
42169
document.querySelectorAll('.nav-btn').forEach(btn => {
@@ -58,6 +185,9 @@ class App {
58185
});
59186
document.getElementById('btn-self-test-stop').addEventListener('click', () => this.stopSelfTest());
60187

188+
this.applyEndpointToRelayInputs(this.defaultEndpointUrl);
189+
this.bindRelayInputSync();
190+
61191
// History
62192
document.getElementById('btn-refresh-history').addEventListener('click', () => {
63193
this.ws.send('list-results', { tool: document.getElementById('history-tool-filter').value || undefined });
@@ -105,6 +235,7 @@ class App {
105235
this.renderToolList();
106236
this.selfTestUI.setTools(this.tools);
107237
this.historyUI.setTools(this.tools);
238+
this.maybeAutoRunSelfTest();
108239
}
109240

110241
renderToolList() {
@@ -163,6 +294,8 @@ class App {
163294
document.getElementById('tool-description').textContent = this.selectedTool.description || '';
164295

165296
this.paramForm.render(this.selectedTool.parameters, document.getElementById('param-form'));
297+
this.applyEndpointToRelayInputs(this.defaultEndpointUrl);
298+
this.bindRelayInputSync();
166299
this.outputPanel.setFilters(this.selectedTool.filters);
167300
this.rendererLoader.unload();
168301

@@ -181,6 +314,10 @@ class App {
181314
state.runId = null;
182315
state.status = 'starting';
183316
state.exitCode = null;
317+
const endpoint = (params.relay_url || params.endpoint_url || '').trim();
318+
if (endpoint) {
319+
this.setEndpointUrl(endpoint);
320+
}
184321

185322
this.ws.send('start-run', { toolId: this.selectedTool.name, params });
186323
document.getElementById('output-section').classList.remove('hidden');
@@ -426,9 +563,12 @@ class App {
426563
}
427564

428565
startSelfTest() {
429-
const relayUrl = document.getElementById('st-relay-url').value;
566+
const relayUrl = document.getElementById('st-relay-url').value.trim();
430567
const transport = document.getElementById('st-transport').value;
431568
const draft = document.getElementById('st-draft').value;
569+
if (relayUrl) {
570+
this.setEndpointUrl(relayUrl);
571+
}
432572
this.ws.send('start-self-test', { relayUrl, transport, draft });
433573
document.getElementById('btn-self-test-run').classList.add('hidden');
434574
document.getElementById('btn-self-test-stop').classList.remove('hidden');

0 commit comments

Comments
 (0)