86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package atspi_test
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.stormux.org/storm/cthulhu/internal/atspi"
|
|
"git.stormux.org/storm/cthulhu/internal/presentation"
|
|
)
|
|
|
|
// GTK 4 popover menu items leave Name empty and point LABELLED_BY at an
|
|
// internal label whose role is invalid; only its text holds the item's label.
|
|
func TestNativeGTK4MenuItemLabels(t *testing.T) {
|
|
if os.Getenv("CTHULHU_NATIVE_GTK4_MENU_LABELS") != "1" {
|
|
t.Skip("requires isolated GTK 4 menu label fixture")
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second)
|
|
defer cancel()
|
|
adapter := atspi.New()
|
|
if err := adapter.Start(ctx); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer stopCancel()
|
|
if err := adapter.Stop(stopCtx); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}()
|
|
tree, err := adapter.CaptureDesktop(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
root, err := tree.Root()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var items []atspi.Snapshot
|
|
var walk func(atspi.ObjectReference)
|
|
walk = func(ref atspi.ObjectReference) {
|
|
snapshot, err := tree.Resolve(ref)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if snapshot.Role == "menu item" || snapshot.Role == "check menu item" || snapshot.Role == "radio menu item" {
|
|
items = append(items, snapshot)
|
|
}
|
|
child, ok, err := tree.FirstChild(ref)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for ok {
|
|
walk(child)
|
|
child, ok, err = tree.NextSibling(child)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
walk(root)
|
|
for _, want := range []string{"New Message", "Add Account…", "Group into Conversations", "All Messages"} {
|
|
t.Run(want, func(t *testing.T) {
|
|
for _, item := range items {
|
|
if item.Name == want {
|
|
if spoken := presentation.FocusText(item); !strings.Contains(spoken, want) {
|
|
t.Errorf("speech %q omits label %q", spoken, want)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
names := make([]string, 0, len(items))
|
|
for _, item := range items {
|
|
names = append(names, item.Role+": "+item.Name)
|
|
}
|
|
t.Errorf("no menu item named %q; captured %q", want, names)
|
|
})
|
|
}
|
|
}
|