// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package atspi import ( "context" "os" "os/exec" "testing" "time" ) func TestNativeBrowserArticleContext(t *testing.T) { if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { t.Skip("requires private browser session") } ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() adapter := New() if err := adapter.Start(ctx); err != nil { t.Fatal(err) } defer func() { stop, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() if err := adapter.Stop(stop); err != nil { t.Error(err) } }() if out, err := exec.CommandContext(ctx, "xdotool", "key", "F9").CombinedOutput(); err != nil { t.Fatalf("focus: %s: %v", out, err) } for { select { case <-ctx.Done(): t.Fatal("missing article control focus", ctx.Err()) case event := <-adapter.Events(): if (event.Type != FocusEvent && event.Type != FocusedStateEvent) || event.Source.Name != "Reply" { continue } for _, ancestor := range event.Source.SpeechContext { if ancestor.Role == "article" && ancestor.Name == "Sample author A message with readable contents. Today at noon" { return } } t.Fatalf("message article missing from speech context: %+v", event.Source.SpeechContext) } } }