mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-11 05:06:15 +00:00
Refreshes docs/images/ui-{settings,devices,sync,migration}.png by
driving the web UI in chromedp against a synthetic speaker, so
documentation can be regenerated without real hardware and without
leaking personal data from the local network.
Three independent pieces:
- pkg/service/testing/fakespeaker — embeddable library serving the
HTTP and telnet surface the migration wizard probes (/info,
/presets, /recents and a getpdo CurrentSystemConfiguration reply
that places the device on the unmigrated happy path).
- cmd/dummy-speaker — thin CLI wrapping the library; self-registers
with a running service via POST /setup/devices.
- scripts/screenshots — chromedp runner driven by a JSON manifest;
decoupled from speaker/service setup so it can target any backend
URL. run.sh orchestrates a one-shot end-to-end capture and seeds
settings.json with a generic hostname plus discovery disabled to
keep real-network state out of the captures.
Captures are at DPR=2 for retina-sharp text.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
82 lines
1.5 KiB
Go
82 lines
1.5 KiB
Go
package fakespeaker
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"net"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestTelnetServerBannerAndGetpdo(t *testing.T) {
|
|
s, err := Start(Config{TelnetListen: "127.0.0.1:0"})
|
|
if err != nil {
|
|
t.Fatalf("start: %v", err)
|
|
}
|
|
|
|
t.Cleanup(func() {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
|
|
_ = s.Stop(ctx)
|
|
})
|
|
|
|
if s.TelnetAddr() == "" {
|
|
t.Fatalf("telnet listener not started")
|
|
}
|
|
|
|
conn, err := net.DialTimeout("tcp", s.TelnetAddr(), 2*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("dial: %v", err)
|
|
}
|
|
|
|
defer func() { _ = conn.Close() }()
|
|
|
|
_ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
|
|
|
|
reader := bufio.NewReader(conn)
|
|
|
|
banner, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
t.Fatalf("read banner: %v", err)
|
|
}
|
|
|
|
if !strings.Contains(banner, "Bose SoundTouch") {
|
|
t.Errorf("banner = %q, want substring %q", banner, "Bose SoundTouch")
|
|
}
|
|
|
|
if _, err := conn.Write([]byte("getpdo CurrentSystemConfiguration\r\n")); err != nil {
|
|
t.Fatalf("write: %v", err)
|
|
}
|
|
|
|
_ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
|
|
|
|
buf := make([]byte, 1024)
|
|
|
|
var got strings.Builder
|
|
|
|
for {
|
|
n, err := conn.Read(buf)
|
|
if n > 0 {
|
|
got.Write(buf[:n])
|
|
}
|
|
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
if strings.Contains(got.String(), "->OK") {
|
|
break
|
|
}
|
|
}
|
|
|
|
out := got.String()
|
|
|
|
for _, want := range []string{"margeServerUrl", "streaming.bose.com", "swUpdateUrl"} {
|
|
if !strings.Contains(out, want) {
|
|
t.Errorf("response missing %q\nfull response:\n%s", want, out)
|
|
}
|
|
}
|
|
}
|