Files
openswarm/backend/tests/test_browser_submit_click.py
T

75 lines
3.8 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Container-scoped submit tier: the middle rung between the below-composer index pick and the
by-name 'Send' last resort, plus the expression builder's escaping. The JS itself is proven live
(X modal resolves tweetButton, inline resolves tweetButtonInline at hop 20); these tests pin the
tier ORDER and the fail-safe parse."""
import pytest
from backend.apps.agents.browser import browser_send_script as ss
from backend.apps.agents.browser import browser_submit_click as sc
from backend.apps.agents.browser.browser_agent import send_submit_index_in_state
# Committed fill whose submit ranks OUT of the capped listing (the shape that starves the picker).
COMPOSER_FILLED_NO_SEND = '[1]<textbox "I\'m looking for…">\n[24]<textbox "Write a message" value="[test] hello world r9-os">'
COMPOSER_SENT = '[2]<textbox "Write a message">\n[9]<button "Attach">'
def make_exec(eval_result):
calls = {"clicks": []}
async def execute(tool, params, bid, tid):
if tool == "BrowserListInteractives":
return {"text": COMPOSER_SENT}
calls["clicks"].append((tool, params))
if tool == "BrowserEvaluate":
return eval_result
return {"ok": True}
return execute, calls
@pytest.mark.asyncio
async def test_container_submit_tier_between_index_and_by_name():
"""X's compose modal: covered feed rows behind the overlay eat the 60-row cap, so the modal's
own Post never reaches the picker (live 0/2 deliveries). The container tier resolves the
submit inside the composer's own container and clicks it with REAL input; by-name stays last."""
execute, calls = make_exec({"value": {"ok": True, "name": "post", "xPct": 61.0, "yPct": 33.0}})
r = await ss.complete_send("[test] hello world r9-os", COMPOSER_FILLED_NO_SEND,
"b1", "", execute, send_submit_index_in_state, composer_index=24)
assert r["clicked"] is True and r["sent"] is True
tools = [c[0] for c in calls["clicks"]]
assert "BrowserEvaluate" in tools and "BrowserClickByName" not in tools
point = [c for c in calls["clicks"] if c[0] == "BrowserClickPoint"]
assert point and point[0][1] == {"xPercent": 61.0, "yPercent": 33.0}
@pytest.mark.asyncio
async def test_container_submit_miss_falls_to_by_name():
execute, calls = make_exec({"value": {"ok": False, "why": "no submit control in the composer container"}})
r = await ss.complete_send("[test] hello world r9-os", COMPOSER_FILLED_NO_SEND,
"b1", "", execute, send_submit_index_in_state, composer_index=24)
assert r["clicked"] is True
tools = [c[0] for c in calls["clicks"]]
assert tools.index("BrowserEvaluate") < tools.index("BrowserClickByName")
def test_container_submit_expression_escapes_and_truncates():
expr = sc.container_submit_expression('he said "hi" ' + "x" * 60)
assert '\\"hi\\"' in expr # payload lands as a JS string literal, quotes escaped
assert "x" * 30 not in expr # truncated to the 24-char prefix the fill verifier uses
assert '"post"' in expr and '"send"' in expr
def test_clean_button_name_strips_shortcut_suffix_and_bidi():
# Gmail's real Send accessible name: 'Send (⌘Enter)'
assert sc.clean_button_name("Send (⌘Enter)") == "send"
assert sc.clean_button_name(" Post ") == "post"
assert sc.clean_button_name("Reply (Ctrl-Enter)") == "reply"
assert sc.clean_button_name("") == ""
def test_parse_eval_value_reads_value_text_and_garbage():
assert sc.parse_eval_value({"value": {"ok": True}}) == {"ok": True}
assert sc.parse_eval_value({"text": '{"ok": false, "why": "x"}'}) == {"ok": False, "why": "x"}
assert sc.parse_eval_value({"text": "not json"}) is None
assert sc.parse_eval_value({"error": "boom"}) is None
assert sc.parse_eval_value("weird") is None