Skip to main content
Glama
Southclaws

Storyden

by Southclaws
main.go3.59 kB
package main import ( "context" "fmt" "log" "net/http" "os" "os/exec" "os/signal" "path/filepath" "syscall" "time" ) func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() if err := run(ctx, os.Args[1:]); err != nil { log.Fatal(err) } } func run(ctx context.Context, playwrightArgs []string) error { timestamp := time.Now().Format(time.RFC3339) e2eDir := filepath.Join("tests", "e2e-data") dataDir := filepath.Join(e2eDir, timestamp) relDir := "./" + dataDir if err := os.MkdirAll(dataDir, 0o755); err != nil { return fmt.Errorf("failed to create data directory: %w", err) } dbPath := filepath.Join(relDir, "data.db") dbURL := fmt.Sprintf("sqlite://./%s?_pragma=foreign_keys(1)", dbPath) backendBinary := "./backend.exe" log.Printf("Starting e2e test with data directory: %s api binary: %s", dataDir, backendBinary) backendCmd := exec.CommandContext(ctx, backendBinary) backendCmd.Dir = e2eDir backendCmd.Env = []string{ fmt.Sprintf("DATABASE_URL=%s", dbURL), "LISTEN_ADDR=0.0.0.0:8001", "PROXY_FRONTEND_ADDRESS=http://localhost:3001", "PUBLIC_API_ADDRESS=http://localhost:8001", "PUBLIC_WEB_ADDRESS=http://localhost:3001", } backendCmd.Stdout = os.Stdout backendCmd.Stderr = os.Stderr if err := backendCmd.Start(); err != nil { return fmt.Errorf("failed to start backend: %w", err) } defer stopProcess("backend", backendCmd) frontendCmd := exec.CommandContext(ctx, "yarn", "start", "--port", "3001") frontendCmd.Dir = "web" frontendCmd.Env = append(os.Environ(), "PUBLIC_API_ADDRESS=http://localhost:8001", "PUBLIC_WEB_ADDRESS=http://localhost:3001", ) frontendCmd.Stdout = os.Stdout frontendCmd.Stderr = os.Stderr if err := frontendCmd.Start(); err != nil { return fmt.Errorf("failed to start frontend: %w", err) } defer stopProcess("frontend", frontendCmd) log.Println("Waiting for services to be ready...") if err := waitForBackend(ctx, "http://localhost:8001/", 60*time.Second); err != nil { return fmt.Errorf("backend did not become ready: %w", err) } log.Println("Services ready, running Playwright tests...") playwrightCmdArgs := append([]string{"playwright", "test"}, playwrightArgs...) playwrightCmd := exec.CommandContext(ctx, "npx", playwrightCmdArgs...) playwrightCmd.Dir = "web" playwrightCmd.Stdout = os.Stdout playwrightCmd.Stderr = os.Stderr if err := playwrightCmd.Run(); err != nil { return fmt.Errorf("playwright tests failed: %w", err) } log.Println("E2E tests completed successfully!") return nil } func stopProcess(name string, cmd *exec.Cmd) { if cmd == nil || cmd.Process == nil { return } log.Println("Stopping", name, "...") _ = cmd.Process.Signal(syscall.SIGTERM) done := make(chan error, 1) go func() { done <- cmd.Wait() }() select { case err := <-done: if err != nil { log.Println(name, "exited with:", err) } case <-time.After(10 * time.Second): log.Println(name, "did not stop in time; killing") _ = cmd.Process.Kill() <-done } } func waitForBackend(ctx context.Context, url string, timeout time.Duration) error { client := &http.Client{Timeout: 2 * time.Second} deadline := time.Now().Add(timeout) for time.Now().Before(deadline) { select { case <-ctx.Done(): return ctx.Err() default: } resp, err := client.Get(url) if err == nil && resp.StatusCode == http.StatusOK { resp.Body.Close() return nil } if resp != nil { resp.Body.Close() } time.Sleep(1 * time.Second) } return fmt.Errorf("timeout waiting for backend at %s", url) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server