fix: bind Cua pixel actions to current screenshot geometry
Correct native scroll scaling, reject stale or out-of-bounds pixel targets, and scope DPI awareness to geometry reads. Package adapter 0.36.0+artemis.3 and document the high-effort cross-device verification. Validation: Go tests and vet, packaged MCP schema and handshake, Python checks, and user-run high-effort task completed with a passed verdict and explicit coverage limits.
This commit is contained in:
1 parent
9c98b6bf8a
commit
889a951c9b
13 files changed
+363
-19
No files matched your search
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func fixtureFrame(w, h int) pointerFrame {
|
||||
return pointerFrame{"current", w, h, obj{"left": -2560, "top": 120, "width": 2560, "height": 1540}}
|
||||
}
|
||||
|
||||
func TestScrollMapsActualNativeCaptureWithoutDPIOrWindowOffset(t *testing.T) {
|
||||
// Reproduce the task's 2558x1538 -> 1280x770 image transition. Window
|
||||
// position and OS logical-screen dimensions must never affect this ratio.
|
||||
f := fixtureFrame(1280, 770)
|
||||
args := obj{"pid": 1, "window_id": 2, "capture_id": "current", "x": 900, "y": 600, "direction": "down"}
|
||||
got, err := nativeScrollArgs(f, args, func() (pointerFrame, error) { return fixtureFrame(2558, 1538), nil })
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if math.Abs(got["x"].(float64)-1798.59375) > 0.0001 || math.Abs(got["y"].(float64)-1198.441558) > 0.0001 {
|
||||
t.Fatalf("incorrect mapping: %v", got)
|
||||
}
|
||||
if _, ok := got["capture_id"]; ok {
|
||||
t.Fatal("upstream scroll does not support capture_id")
|
||||
}
|
||||
if args["x"] != 900 || args["capture_id"] != "current" {
|
||||
t.Fatal("input evidence mutated")
|
||||
}
|
||||
if got["pid"] != 1 || got["window_id"] != 2 || got["direction"] != "down" {
|
||||
t.Fatal("target changed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNativeScrollAndNonCroppedCapture(t *testing.T) {
|
||||
for _, size := range [][2]int{{2558, 1538}, {2560, 1540}, {1280, 770}} {
|
||||
f := fixtureFrame(size[0], size[1])
|
||||
args := obj{"capture_id": "current", "x": 200.5, "y": 300.25}
|
||||
got, err := nativeScrollArgs(f, args, func() (pointerFrame, error) { return f, nil })
|
||||
if err != nil || got["x"] != 200.5 || got["y"] != 300.25 {
|
||||
t.Fatalf("native coordinates changed: %v %v", got, err)
|
||||
}
|
||||
}
|
||||
// WGC can have a different native extent than a one-pixel DWM crop.
|
||||
f := fixtureFrame(1280, 770)
|
||||
got, err := nativeScrollArgs(f, obj{"capture_id": "current", "x": 640, "y": 385}, func() (pointerFrame, error) { return fixtureFrame(2560, 1540), nil })
|
||||
if err != nil || got["x"] != float64(1280) || got["y"] != float64(770) {
|
||||
t.Fatalf("assumed DWM crop: %v %v", got, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidCoordinatesNeverReachNativeProbe(t *testing.T) {
|
||||
f := fixtureFrame(1280, 770)
|
||||
for _, bad := range []obj{
|
||||
{"capture_id": "current", "x": 1700, "y": 1000}, // Actual failing task.
|
||||
{"capture_id": "old", "x": 900, "y": 600},
|
||||
{"x": 900, "y": 600},
|
||||
{"capture_id": "current", "x": -1, "y": 0},
|
||||
{"capture_id": "current", "x": 1280, "y": 0},
|
||||
{"capture_id": "current", "x": 0, "y": 770},
|
||||
{"capture_id": "current", "x": "900", "y": 600},
|
||||
{"capture_id": "current", "x": math.NaN(), "y": 600},
|
||||
{"capture_id": "current", "x": 900, "y": math.Inf(1)},
|
||||
} {
|
||||
_, err := nativeScrollArgs(f, bad, func() (pointerFrame, error) { t.Fatal("invalid coordinates reached probe"); return f, nil })
|
||||
if err == nil {
|
||||
t.Fatalf("accepted %v", bad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScrollRejectsMovedResizedOrDifferentCrop(t *testing.T) {
|
||||
f := fixtureFrame(1280, 770)
|
||||
for _, kind := range []string{"moved", "resized", "crop", "missing"} {
|
||||
native := fixtureFrame(2558, 1538)
|
||||
switch kind {
|
||||
case "moved":
|
||||
native.window["left"] = 0
|
||||
case "resized":
|
||||
native.window["width"] = 1920
|
||||
case "crop":
|
||||
native.height = 1000
|
||||
case "missing":
|
||||
native.width = 0
|
||||
}
|
||||
_, err := nativeScrollArgs(f, obj{"capture_id": "current", "x": 900, "y": 600}, func() (pointerFrame, error) { return native, nil })
|
||||
if err == nil {
|
||||
t.Fatal(kind)
|
||||
}
|
||||
}
|
||||
_, err := nativeScrollArgs(f, obj{"capture_id": "current", "x": 900, "y": 600}, func() (pointerFrame, error) { return pointerFrame{}, errors.New("capture disconnected") })
|
||||
if err == nil {
|
||||
t.Fatal("missing capture was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClickAndBothDragEndpointsUseLatestFrame(t *testing.T) {
|
||||
f := fixtureFrame(1280, 770)
|
||||
click := obj{"capture_id": "current", "x": 1279, "y": 769}
|
||||
if err := f.validate("click_at", click); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if click["x"] != 1279 || click["y"] != 769 {
|
||||
t.Fatal("click scaled twice")
|
||||
}
|
||||
drag := obj{"capture_id": "current", "from_x": 0, "from_y": 0, "to_x": 1279, "to_y": 769}
|
||||
if err := f.validate("drag", drag); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, key := range []string{"from_x", "from_y", "to_x", "to_y"} {
|
||||
bad := copyArgs(drag)
|
||||
bad[key] = 3000
|
||||
if f.validate("drag", bad) == nil {
|
||||
t.Fatal("accepted out of bounds " + key)
|
||||
}
|
||||
}
|
||||
drag["capture_id"] = "old"
|
||||
if f.validate("drag", drag) == nil {
|
||||
t.Fatal("accepted stale drag")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllPixelSchemasRequireCapture(t *testing.T) {
|
||||
a := newAdapter(nil)
|
||||
for _, name := range []string{"click_at", "scroll", "drag"} {
|
||||
found := false
|
||||
for _, key := range items(a.schemas[name]["required"]) {
|
||||
if key == "capture_id" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatal(name + " lacks capture binding")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user