Version bump and some lable/relation fixes.

This commit is contained in:
Storm Dragon committed 2026-10-18 22:11:54 -04:00
1 parent d717b93849
commit 396efbd7c5
15 files changed
+474 -8

No files matched your search

@@ -0,0 +1,94 @@
// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package presentation
import (
"bufio"
"context"
"fmt"
"os"
"os/exec"
"strings"
"testing"
"time"
"git.stormux.org/storm/cthulhu/internal/atspi"
)
func TestNativeTextLabelRelations(t *testing.T) {
if os.Getenv("CTHULHU_NATIVE_TEXT_LABELS") != "1" {
t.Skip("requires private GTK/AT-SPI session")
}
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
adapter := atspi.New()
if err := adapter.Start(ctx); err != nil {
t.Fatal(err)
}
defer adapter.Stop(context.Background())
fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../tests/text_label_fixture.py")
fixture.Env = append(os.Environ(), "NO_AT_BRIDGE=0", "GTK_MODULES=gail:atk-bridge")
stdin, err := fixture.StdinPipe()
if err != nil {
t.Fatal(err)
}
stdout, err := fixture.StdoutPipe()
if err != nil {
t.Fatal(err)
}
fixture.Stderr = os.Stderr
if err := fixture.Start(); err != nil {
t.Fatal(err)
}
defer func() { stdin.Close(); fixture.Wait() }()
if scanner := bufio.NewScanner(stdout); !scanner.Scan() || scanner.Text() != "ready" {
t.Fatal("fixture did not start")
}
var previous atspi.ObjectID
for index, probe := range []struct{ name, value string }{
{"Destination:", ""},
{"Display name:", "Example document"},
{"Preferred name", "Example value"},
{"Secret:", ""},
{"", "Unlabeled value"},
{"Account identifier", ""},
} {
if _, err := fmt.Fprintln(stdin, index); err != nil {
t.Fatal(err)
}
waitFocus:
for {
select {
case <-ctx.Done():
t.Fatal("missing entry focus", index)
case event := <-adapter.Events():
if (event.Type != atspi.FocusEvent && event.Type != atspi.FocusedStateEvent) || !event.Source.Focused {
continue
}
snapshot := event.Source
if snapshot.Role != "text" && snapshot.Role != "password text" {
continue
}
if snapshot.ID() == previous {
continue
}
previous = snapshot.ID()
if snapshot.Name != probe.name {
t.Errorf("entry %d name = %q, want %q", index, snapshot.Name, probe.name)
}
speech := FocusText(snapshot)
for _, part := range []string{probe.name, probe.value} {
if part != "" && !strings.Contains(speech, part) {
t.Errorf("entry %d speech %q omits %q", index, speech, part)
}
}
if strings.Contains(speech, "private fixture value") {
t.Error("password content leaked into speech")
}
break waitFocus
}
}
}
}