mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
test(ioscompanion): add gated simulator integration smoke test
This commit is contained in:
1 parent
02e4010344
commit
bc1b71f5e2
1 file changed
+105
@@ -0,0 +1,105 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestIntegrationAccessibilityInfo spawns a local companion against a booted
|
||||
// simulator and exercises a real AccessibilityInfo call. It is gated behind
|
||||
// SANDERLING_IOS_INTEGRATION so it never runs by default.
|
||||
func TestIntegrationAccessibilityInfo(t *testing.T) {
|
||||
if os.Getenv("SANDERLING_IOS_INTEGRATION") == "" {
|
||||
t.Skip("set SANDERLING_IOS_INTEGRATION=1 to run the integration smoke test")
|
||||
}
|
||||
|
||||
udid := bootedSimulatorUDID(t)
|
||||
port := freePort(t)
|
||||
|
||||
companionBinary := "/opt/homebrew/bin/idb_companion"
|
||||
command := exec.Command(companionBinary, "--udid", udid, "--grpc-port", strconv.Itoa(port))
|
||||
if err := command.Start(); err != nil {
|
||||
t.Fatalf("start companion: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = command.Process.Kill()
|
||||
_, _ = command.Process.Wait()
|
||||
}()
|
||||
|
||||
address := net.JoinHostPort("127.0.0.1", strconv.Itoa(port))
|
||||
waitForListener(t, address)
|
||||
|
||||
companion, err := Dial(address)
|
||||
if err != nil {
|
||||
t.Fatalf("Dial: %v", err)
|
||||
}
|
||||
defer companion.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
info, err := companion.AccessibilityInfo(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("AccessibilityInfo: %v", err)
|
||||
}
|
||||
if strings.TrimSpace(info) == "" {
|
||||
t.Fatal("AccessibilityInfo returned empty json")
|
||||
}
|
||||
}
|
||||
|
||||
func bootedSimulatorUDID(t *testing.T) string {
|
||||
t.Helper()
|
||||
output, err := exec.Command("xcrun", "simctl", "list", "devices", "booted", "--json").Output()
|
||||
if err != nil {
|
||||
t.Fatalf("simctl list: %v", err)
|
||||
}
|
||||
var parsed struct {
|
||||
Devices map[string][]struct {
|
||||
UDID string `json:"udid"`
|
||||
State string `json:"state"`
|
||||
} `json:"devices"`
|
||||
}
|
||||
if err := json.Unmarshal(output, &parsed); err != nil {
|
||||
t.Fatalf("parse simctl json: %v", err)
|
||||
}
|
||||
for _, devices := range parsed.Devices {
|
||||
for _, device := range devices {
|
||||
if device.State == "Booted" {
|
||||
return device.UDID
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Skip("no booted simulator available")
|
||||
return ""
|
||||
}
|
||||
|
||||
func freePort(t *testing.T) int {
|
||||
t.Helper()
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("reserve port: %v", err)
|
||||
}
|
||||
port := listener.Addr().(*net.TCPAddr).Port
|
||||
_ = listener.Close()
|
||||
return port
|
||||
}
|
||||
|
||||
func waitForListener(t *testing.T, address string) {
|
||||
t.Helper()
|
||||
deadline := time.Now().Add(20 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
conn, err := net.DialTimeout("tcp", address, time.Second)
|
||||
if err == nil {
|
||||
_ = conn.Close()
|
||||
return
|
||||
}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
}
|
||||
t.Fatalf("companion did not listen on %s", address)
|
||||
}
|
||||
Reference in new issue
Block a user