aboutsummaryrefslogtreecommitdiff
path: root/scripts/test_windows_input.py
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-20 00:21:32 +0200
committerGitHub <noreply@github.com>2026-09-20 00:21:32 +0200
commit9d29441a84858780f80ff1bc35ce9c0c5f43b0c9 (patch)
treea8754c76363bec0b5f5421416067f9a8421d027b /scripts/test_windows_input.py
parent856b64b9bfd41b9d3d82e2375ed5b4bf941fda28 (diff)
test(windows): distinguish clipboard paste origin in input gauntlet (#4394)
* test(windows): distinguish clipboard paste origin in input gauntlet refs #4314 * test(windows): correct gauntlet paste-origin evidence refs #4314
Diffstat (limited to 'scripts/test_windows_input.py')
-rw-r--r--scripts/test_windows_input.py39
1 files changed, 38 insertions, 1 deletions
diff --git a/scripts/test_windows_input.py b/scripts/test_windows_input.py
index 38868843..a844ea62 100644
--- a/scripts/test_windows_input.py
+++ b/scripts/test_windows_input.py
@@ -1,7 +1,7 @@
"""Portable tests of the gauntlet's oracle, not Windows input qualification."""
import copy
import unittest
-from scripts.windows_input.report import catalogue, channel_identity_errors, herdr_protocol_label, known_host_gap, qualification_matrix, summarize, verdict
+from scripts.windows_input.report import classification_of_client_events, catalogue, channel_identity_errors, herdr_protocol_label, known_host_gap, qualification_matrix, summarize, verdict
class WindowsInputGauntletTests(unittest.TestCase):
@@ -95,12 +95,49 @@ class WindowsInputGauntletTests(unittest.TestCase):
staged = b"\x1b[200~C:\\Temp\\herdr-clipboard-images-user\\image.png\x1b[201~"
self.assertEqual(verdict(case, "legacy", {**self.evidence, "path": "direct", "hex": empty_paste.hex()})[0], "pass")
remote = {**self.evidence, "path": "herdr-remote", "hex": staged.hex(),
+ "paste_origin": "empty-paste",
"staged_image_sha256": case["expected"]["legacy"]["sha256"]}
self.assertEqual(verdict(case, "legacy", remote)[0], "pass")
self.assertEqual(verdict(case, "legacy", {**remote, "staged_image_sha256": "0" * 64})[0], "fail")
self.assertEqual(verdict(case, "legacy", {**self.evidence, "path": "herdr-remote", "hex": empty_paste.hex()})[0], "fail")
self.assertEqual(verdict(case, "legacy", {**self.evidence, "path": "herdr", "hex": empty_paste.hex()})[0], "not_run")
+ def test_remote_clipboard_image_rejects_a_paste_the_terminal_issued(self):
+ # A staged PNG that came from a terminal-issued text paste proves nothing
+ # about the empty-paste bridge (#4314), and a staged PNG with no mapper
+ # evidence at all must not qualify the bridge either.
+ case = self.cases["clipboard-image"]
+ staged = b"\x1b[200~C:\\Temp\\herdr-clipboard-images-user\\image.png\x1b[201~"
+ remote = {**self.evidence, "path": "herdr-remote", "hex": staged.hex(),
+ "staged_image_sha256": case["expected"]["legacy"]["sha256"]}
+ self.assertEqual(verdict(case, "legacy", {**remote, "paste_origin": "terminal-paste"})[0], "fail")
+ for weak in ("none", "key-event", None):
+ self.assertEqual(verdict(case, "legacy", {**remote, "paste_origin": weak})[0], "inconclusive", weak)
+ self.assertEqual(verdict(case, "legacy", {**remote, "paste_origin": "empty-paste"})[0], "pass")
+ direct = {**self.evidence, "path": "direct", "hex": b"\x1b[200~\x1b[201~".hex()}
+ self.assertEqual(verdict(case, "legacy", {**direct, "paste_origin": "terminal-paste"})[0], "fail")
+ self.assertEqual(verdict(case, "legacy", {**direct, "paste_origin": "empty-paste"})[0], "pass")
+
+ def test_client_event_trace_classifies_paste_origin(self):
+ self.assertEqual(classification_of_client_events(None), None)
+ self.assertEqual(classification_of_client_events([]), "none")
+ self.assertEqual(
+ classification_of_client_events(['mapped_event_groups=[Paste { text: "" }]']),
+ "empty-paste")
+ self.assertEqual(
+ classification_of_client_events(['mapped_event_groups=[Paste { text: "hello" }]']),
+ "terminal-paste")
+ self.assertEqual(
+ classification_of_client_events(
+ ["mapped_event_groups=[Key { code: Char('v'), modifiers: 0, kind: Press }]"]),
+ "key-event")
+ # A release alone is not a consumed press.
+ self.assertEqual(
+ classification_of_client_events(
+ ["mapped_event_groups=[Key { code: Char('v'), modifiers: 0, kind: Release }]"]),
+ "none")
+ self.assertEqual(classification_of_client_events(["not a trace line", 7]), None)
+
def test_mouse_interleave_requires_ordered_motion_and_paste(self):
case = self.cases["mouse-interleave"]
motion = b"\x1b[<35;10;5M"