From cf62b369c692b7554a9ba728c310e77a701a3770 Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 4 Jul 2025 18:27:04 +0800 Subject: [PATCH 1/3] feat: support to set the server arguments on desktop --- console/atest-desktop/index.html | 48 ++++++++++++++++++++++++-------- console/atest-desktop/main.js | 17 +++++++++-- console/atest-desktop/preload.js | 3 ++ 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/console/atest-desktop/index.html b/console/atest-desktop/index.html index b7f675e2..cbf766d6 100644 --- a/console/atest-desktop/index.html +++ b/console/atest-desktop/index.html @@ -9,19 +9,41 @@ -
+
Server Status
- - -
- Port: -
-
- -
-
Log
- + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
Log + +
+ + + +
@@ -63,9 +85,11 @@ window.setInterval(loadServerStatus, 2000) const portInput = document.getElementById('port'); +const extensionRegistry = document.getElementById('extension-registry'); (async function() { portInput.value = await window.electronAPI.getPort() + extensionRegistry.value = await window.electronAPI.getExtensionRegistry() })(); - \ No newline at end of file + diff --git a/console/atest-desktop/main.js b/console/atest-desktop/main.js index dd21b458..c5119cec 100644 --- a/console/atest-desktop/main.js +++ b/console/atest-desktop/main.js @@ -1,5 +1,5 @@ /* -Copyright 2024 API Testing Authors. +Copyright 2024-2025 API Testing Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -117,6 +117,9 @@ menu.append(new MenuItem({ Menu.setApplicationMenu(menu) let serverProcess; +let serverPort; +let setExtensionRegistry = "ghcr.io"; + // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. @@ -129,6 +132,15 @@ app.whenReady().then(() => { ipcMain.on('control', (e, okCallback, errCallback) => { server.control(okCallback, errCallback) }) + ipcMain.handle('setPort', (port) => { + serverPort = port; + }) + ipcMain.handle('setExtensionRegistry', (registry) => { + setExtensionRegistry = registry + }) + ipcMain.handle('getExtensionRegistry', () => { + return setExtensionRegistry + }) ipcMain.handle('getHomePage', server.getHomePage) ipcMain.handle('getPort', () => { return server.getPort() @@ -181,6 +193,7 @@ const startServer = () => { "server", "--http-port", server.getPort(), "--port=0", + `--extension-registry=${setExtensionRegistry}`, "--local-storage", path.join(homeData, "*.yaml") ]) serverProcess.stdout.on('data', (data) => { @@ -222,4 +235,4 @@ function getLogLevel() { } // In this file you can include the rest of your app's specific main process -// code. You can also put them in separate files and require them here. \ No newline at end of file +// code. You can also put them in separate files and require them here. diff --git a/console/atest-desktop/preload.js b/console/atest-desktop/preload.js index bd250c3c..ead1c18d 100644 --- a/console/atest-desktop/preload.js +++ b/console/atest-desktop/preload.js @@ -36,5 +36,8 @@ contextBridge.exposeInMainWorld('electronAPI', { control: (okCallback, errCallback) => ipcRenderer.send('control', okCallback, errCallback), getHomePage: () => ipcRenderer.invoke('getHomePage'), getPort: () => ipcRenderer.invoke('getPort'), + setPort: (port) => ipcRenderer.send('setPort', port), + setExtensionRegistry: (registry) => ipcRenderer.send('setExtensionRegistry', registry), + getExtensionRegistry: () => ipcRenderer.invoke('getExtensionRegistry'), getHealthzUrl: () => ipcRenderer.invoke('getHealthzUrl'), }) From 0e71eff60f7c163059c468f739dc0b0387d667f7 Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 4 Jul 2025 23:04:16 +0800 Subject: [PATCH 2/3] test pass for setting extension registry --- console/atest-desktop/index.html | 9 +++++++++ console/atest-desktop/main.js | 22 ++++++++++++---------- console/atest-desktop/preload.js | 4 ++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/console/atest-desktop/index.html b/console/atest-desktop/index.html index cbf766d6..8a928e9f 100644 --- a/console/atest-desktop/index.html +++ b/console/atest-desktop/index.html @@ -85,7 +85,16 @@ window.setInterval(loadServerStatus, 2000) const portInput = document.getElementById('port'); +portInput.addEventListener("input", function(e) { + window.electronAPI.setPort(portInput.value) +}); + const extensionRegistry = document.getElementById('extension-registry'); +extensionRegistry.addEventListener("input", function(e) { + console.log('setExtensionRegistry', extensionRegistry.value) + window.electronAPI.setExtensionRegistry(extensionRegistry.value) +}); + (async function() { portInput.value = await window.electronAPI.getPort() extensionRegistry.value = await window.electronAPI.getExtensionRegistry() diff --git a/console/atest-desktop/main.js b/console/atest-desktop/main.js index c5119cec..3720e28b 100644 --- a/console/atest-desktop/main.js +++ b/console/atest-desktop/main.js @@ -117,8 +117,8 @@ menu.append(new MenuItem({ Menu.setApplicationMenu(menu) let serverProcess; -let serverPort; -let setExtensionRegistry = "ghcr.io"; +let serverPort = 7788; +let extensionRegistry = "ghcr.io"; // This method will be called when Electron has finished // initialization and is ready to create browser windows. @@ -132,18 +132,20 @@ app.whenReady().then(() => { ipcMain.on('control', (e, okCallback, errCallback) => { server.control(okCallback, errCallback) }) - ipcMain.handle('setPort', (port) => { - serverPort = port; + ipcMain.handle('setPort', (e, port) => { + console.log('setPort', port) + serverPort = port; }) - ipcMain.handle('setExtensionRegistry', (registry) => { - setExtensionRegistry = registry + ipcMain.handle('setExtensionRegistry', (e, registry) => { + console.log('setExtensionRegistry', registry) + extensionRegistry = registry }) ipcMain.handle('getExtensionRegistry', () => { - return setExtensionRegistry + return extensionRegistry }) ipcMain.handle('getHomePage', server.getHomePage) ipcMain.handle('getPort', () => { - return server.getPort() + return serverPort }) ipcMain.handle('getHealthzUrl', server.getHealthzUrl) @@ -191,9 +193,9 @@ const startServer = () => { serverProcess = spawn(atestFromHome, [ "server", - "--http-port", server.getPort(), + `--http-port=${serverPort}`, "--port=0", - `--extension-registry=${setExtensionRegistry}`, + `--extension-registry=${extensionRegistry}`, "--local-storage", path.join(homeData, "*.yaml") ]) serverProcess.stdout.on('data', (data) => { diff --git a/console/atest-desktop/preload.js b/console/atest-desktop/preload.js index ead1c18d..194e7c95 100644 --- a/console/atest-desktop/preload.js +++ b/console/atest-desktop/preload.js @@ -36,8 +36,8 @@ contextBridge.exposeInMainWorld('electronAPI', { control: (okCallback, errCallback) => ipcRenderer.send('control', okCallback, errCallback), getHomePage: () => ipcRenderer.invoke('getHomePage'), getPort: () => ipcRenderer.invoke('getPort'), - setPort: (port) => ipcRenderer.send('setPort', port), - setExtensionRegistry: (registry) => ipcRenderer.send('setExtensionRegistry', registry), + setPort: (port) => ipcRenderer.invoke('setPort', port), + setExtensionRegistry: (registry) => ipcRenderer.invoke('setExtensionRegistry', registry), getExtensionRegistry: () => ipcRenderer.invoke('getExtensionRegistry'), getHealthzUrl: () => ipcRenderer.invoke('getHealthzUrl'), }) From fb3febd38ddc89ce384f8bc1cc4f59d30c0608e9 Mon Sep 17 00:00:00 2001 From: rick Date: Sat, 5 Jul 2025 07:02:26 +0800 Subject: [PATCH 3/3] support to open server on the external broswer --- console/atest-desktop/index.html | 28 +++++++++++++++++++++++++++- console/atest-desktop/main.js | 23 ++++++++++++++++------- console/atest-desktop/preload.js | 3 +++ pkg/server/store_ext_manager.go | 13 ++++++++++++- pkg/server/store_ext_manager_test.go | 1 + 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/console/atest-desktop/index.html b/console/atest-desktop/index.html index 8a928e9f..418c6b83 100644 --- a/console/atest-desktop/index.html +++ b/console/atest-desktop/index.html @@ -12,6 +12,7 @@
Server Status
+
+ + + +
@@ -29,6 +30,14 @@
+ + + +
Log @@ -41,6 +50,7 @@ +
@@ -61,6 +71,15 @@ } }) +document.getElementById('open-from-browser').addEventListener('click', async (e) => { + const address = await window.electronAPI.getHomePage(); + if (address) { + await window.electronAPI.openWithExternalBrowser(address); + } else { + alert('Please start the server first!'); + } +}) + const openServerBut = document.getElementById('open-server-page'); openServerBut.addEventListener('click', async (e) => { window.location = await window.electronAPI.getHomePage() @@ -91,13 +110,20 @@ const extensionRegistry = document.getElementById('extension-registry'); extensionRegistry.addEventListener("input", function(e) { - console.log('setExtensionRegistry', extensionRegistry.value) window.electronAPI.setExtensionRegistry(extensionRegistry.value) }); +const downloadTimeout = document.getElementById('download-timeout'); +downloadTimeout.addEventListener("input", function(e) { + window.electronAPI.setDownloadTimeout(downloadTimeout.value) +}); + (async function() { portInput.value = await window.electronAPI.getPort() extensionRegistry.value = await window.electronAPI.getExtensionRegistry() + downloadTimeout.value = await window.electronAPI.getDownloadTimeout() + + document.getElementById('address').innerText = await window.electronAPI.getHomePage(); })(); diff --git a/console/atest-desktop/main.js b/console/atest-desktop/main.js index 3720e28b..7ed549fa 100644 --- a/console/atest-desktop/main.js +++ b/console/atest-desktop/main.js @@ -119,6 +119,7 @@ Menu.setApplicationMenu(menu) let serverProcess; let serverPort = 7788; let extensionRegistry = "ghcr.io"; +let downloadTimeout = "1m"; // This method will be called when Electron has finished // initialization and is ready to create browser windows. @@ -127,26 +128,33 @@ app.whenReady().then(() => { ipcMain.on('openLogDir', () => { shell.openExternal('file://' + server.getLogfile()) }) + ipcMain.handle('openWithExternalBrowser', (e, address) => { + shell.openExternal(address) + }) ipcMain.on('startServer', startServer) ipcMain.on('stopServer', stopServer) ipcMain.on('control', (e, okCallback, errCallback) => { server.control(okCallback, errCallback) }) + ipcMain.handle('getPort', () => { + return serverPort + }) ipcMain.handle('setPort', (e, port) => { - console.log('setPort', port) serverPort = port; }) + ipcMain.handle('getExtensionRegistry', () => { + return extensionRegistry + }) ipcMain.handle('setExtensionRegistry', (e, registry) => { - console.log('setExtensionRegistry', registry) extensionRegistry = registry }) - ipcMain.handle('getExtensionRegistry', () => { - return extensionRegistry + ipcMain.handle('getDownloadTimeout', () => { + return downloadTimeout }) - ipcMain.handle('getHomePage', server.getHomePage) - ipcMain.handle('getPort', () => { - return serverPort + ipcMain.handle('setDownloadTimeout', (e, timeout) => { + downloadTimeout = timeout }) + ipcMain.handle('getHomePage', server.getHomePage) ipcMain.handle('getHealthzUrl', server.getHealthzUrl) startServer() @@ -195,6 +203,7 @@ const startServer = () => { "server", `--http-port=${serverPort}`, "--port=0", + `--download-timeout=${downloadTimeout}`, `--extension-registry=${extensionRegistry}`, "--local-storage", path.join(homeData, "*.yaml") ]) diff --git a/console/atest-desktop/preload.js b/console/atest-desktop/preload.js index 194e7c95..0c1d8875 100644 --- a/console/atest-desktop/preload.js +++ b/console/atest-desktop/preload.js @@ -31,6 +31,7 @@ window.addEventListener('DOMContentLoaded', () => { contextBridge.exposeInMainWorld('electronAPI', { openLogDir: () => ipcRenderer.send('openLogDir'), + openWithExternalBrowser: (address) => ipcRenderer.invoke('openWithExternalBrowser', address), startServer: () => ipcRenderer.send('startServer'), stopServer: () => ipcRenderer.send('stopServer'), control: (okCallback, errCallback) => ipcRenderer.send('control', okCallback, errCallback), @@ -39,5 +40,7 @@ contextBridge.exposeInMainWorld('electronAPI', { setPort: (port) => ipcRenderer.invoke('setPort', port), setExtensionRegistry: (registry) => ipcRenderer.invoke('setExtensionRegistry', registry), getExtensionRegistry: () => ipcRenderer.invoke('getExtensionRegistry'), + getDownloadTimeout: () => ipcRenderer.invoke('getDownloadTimeout'), + setDownloadTimeout: (timeout) => ipcRenderer.invoke('setDownloadTimeout', timeout), getHealthzUrl: () => ipcRenderer.invoke('getHealthzUrl'), }) diff --git a/pkg/server/store_ext_manager.go b/pkg/server/store_ext_manager.go index 253f49b6..ff34ad94 100644 --- a/pkg/server/store_ext_manager.go +++ b/pkg/server/store_ext_manager.go @@ -160,13 +160,24 @@ func (s *storeExtManager) StopAll() error { serverLogger.Info("stop", "extensions", len(s.processs)) for _, p := range s.processs { if p != nil { - p.Signal(syscall.SIGTERM) + // Use Kill on Windows, Signal on other platforms + if isWindows() { + p.Kill() + } else { + p.Signal(syscall.SIGTERM) + } } } s.stopSingal <- struct{}{} return nil } +// isWindows returns true if the program is running on Windows OS. +func isWindows() bool { + return strings.Contains(strings.ToLower(os.Getenv("OS")), "windows") || + (strings.Contains(strings.ToLower(os.Getenv("GOOS")), "windows")) +} + func (s *storeExtManager) WithDownloader(ociDownloader downloader.PlatformAwareOCIDownloader) { s.ociDownloader = ociDownloader } diff --git a/pkg/server/store_ext_manager_test.go b/pkg/server/store_ext_manager_test.go index 6ce5eee8..c5c06423 100644 --- a/pkg/server/store_ext_manager_test.go +++ b/pkg/server/store_ext_manager_test.go @@ -44,6 +44,7 @@ func TestStoreExtManager(t *testing.T) { err = mgr.Start("go", "") assert.NoError(t, err) + time.Sleep(time.Microsecond * 100) err = mgr.StopAll() assert.NoError(t, err) })