diff --git a/console/atest-desktop/index.html b/console/atest-desktop/index.html index b7f675e2..418c6b83 100644 --- a/console/atest-desktop/index.html +++ b/console/atest-desktop/index.html @@ -9,19 +9,51 @@ -
+
Server Status
- - -
- Port: -
-
- -
-
Log
- +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
Log + +
+ + + + +
@@ -39,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() @@ -63,9 +104,27 @@ 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) { + 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(); })(); - \ No newline at end of file + diff --git a/console/atest-desktop/main.js b/console/atest-desktop/main.js index dd21b458..7ed549fa 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,10 @@ menu.append(new MenuItem({ 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. // Some APIs can only be used after this event occurs. @@ -124,15 +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('getHomePage', server.getHomePage) ipcMain.handle('getPort', () => { - return server.getPort() + return serverPort + }) + ipcMain.handle('setPort', (e, port) => { + serverPort = port; + }) + ipcMain.handle('getExtensionRegistry', () => { + return extensionRegistry }) + ipcMain.handle('setExtensionRegistry', (e, registry) => { + extensionRegistry = registry + }) + ipcMain.handle('getDownloadTimeout', () => { + return downloadTimeout + }) + ipcMain.handle('setDownloadTimeout', (e, timeout) => { + downloadTimeout = timeout + }) + ipcMain.handle('getHomePage', server.getHomePage) ipcMain.handle('getHealthzUrl', server.getHealthzUrl) startServer() @@ -179,8 +201,10 @@ const startServer = () => { serverProcess = spawn(atestFromHome, [ "server", - "--http-port", server.getPort(), + `--http-port=${serverPort}`, "--port=0", + `--download-timeout=${downloadTimeout}`, + `--extension-registry=${extensionRegistry}`, "--local-storage", path.join(homeData, "*.yaml") ]) serverProcess.stdout.on('data', (data) => { @@ -222,4 +246,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..0c1d8875 100644 --- a/console/atest-desktop/preload.js +++ b/console/atest-desktop/preload.js @@ -31,10 +31,16 @@ 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), getHomePage: () => ipcRenderer.invoke('getHomePage'), getPort: () => ipcRenderer.invoke('getPort'), + 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) })