Fix some issues with disabled edit fields.
This commit is contained in:
1 parent
d8b59aa05b
commit
7d720e131d
7 files changed
+240
-11
No files matched your search
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/atspi"
|
||||
"git.stormux.org/storm/cthulhu/internal/review"
|
||||
)
|
||||
|
||||
func TestNativeBrowserDisabledFieldsRemainReadable(t *testing.T) {
|
||||
if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" {
|
||||
t.Skip("requires private browser session")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
|
||||
defer cancel()
|
||||
adapter := atspi.New()
|
||||
if err := adapter.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer adapter.Stop(context.Background())
|
||||
command := func(args ...string) {
|
||||
t.Helper()
|
||||
if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil {
|
||||
t.Fatalf("xdotool: %v: %s", err, output)
|
||||
}
|
||||
}
|
||||
windows, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Browser Probe").Output()
|
||||
if err != nil || len(strings.Fields(string(windows))) == 0 {
|
||||
t.Fatalf("fixture window: %s %v", windows, err)
|
||||
}
|
||||
command("windowfocus", strings.Fields(string(windows))[0])
|
||||
var focus atspi.ObjectID
|
||||
for attempt := 0; attempt < 12 && !focus.Valid(); attempt++ {
|
||||
command("windowfocus", strings.Fields(string(windows))[0])
|
||||
command("key", "--clearmodifiers", "Tab")
|
||||
timer := time.NewTimer(300 * time.Millisecond)
|
||||
waitFocus:
|
||||
for {
|
||||
select {
|
||||
case event := <-adapter.Events():
|
||||
if (event.Type == atspi.FocusEvent || event.Type == atspi.FocusedStateEvent && event.Detail1 == 1) && event.Source.Name == "Read only answer" {
|
||||
focus = event.Source.ID()
|
||||
break waitFocus
|
||||
}
|
||||
case <-timer.C:
|
||||
break waitFocus
|
||||
case <-ctx.Done():
|
||||
t.Fatal(ctx.Err())
|
||||
}
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
if !focus.Valid() {
|
||||
t.Fatal("fixture focus missing")
|
||||
}
|
||||
// Capture before the transition to exercise invalidation of a retained tree.
|
||||
if _, err := adapter.CaptureDocument(ctx, focus); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
command("windowfocus", strings.Fields(string(windows))[0])
|
||||
command("key", "F9")
|
||||
for {
|
||||
select {
|
||||
case event := <-adapter.Events():
|
||||
if event.Type != "object:state-changed:sensitive" || event.Source.Name != "Answer" || event.Detail1 != 0 {
|
||||
continue
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatal("disabled state update missing: ", ctx.Err())
|
||||
}
|
||||
break
|
||||
}
|
||||
worker, err := review.NewWorker(adapter, 2*time.Second)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := worker.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer worker.Stop(context.Background())
|
||||
worker.SyncFocus(focus)
|
||||
for _, step := range []struct {
|
||||
command review.DocumentCaretCommand
|
||||
want string
|
||||
}{
|
||||
{review.CaretDocumentStart, "Before fields"},
|
||||
{review.CaretNextLine, ""}, // Keep the named row, then enter its disabled fields.
|
||||
{review.CaretNextLine, "Solved"},
|
||||
{review.CaretNextCharacter, "o"},
|
||||
{review.CaretNextLine, "Confirmed"},
|
||||
{review.CaretNextLine, "After fields"},
|
||||
{review.CaretPreviousLine, "Confirmed"},
|
||||
{review.CaretPreviousLine, "Solved"},
|
||||
} {
|
||||
if err := worker.MoveDocumentCaret(step.command); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
case result := <-worker.Results():
|
||||
if result.Err != nil || !result.Moved || result.DocumentCaretText != step.want {
|
||||
t.Fatalf("%s: text=%q moved=%t err=%v; want %q", step.command,
|
||||
result.DocumentCaretText, result.Moved, result.Err, step.want)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatal(ctx.Err())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user