Spaces:
Running
Running
File size: 5,258 Bytes
6e4eb30 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | from __future__ import annotations
import asyncio
import json
import pytest
from browser_core import BrowserBridgeError
from javascript_core import run_javascript
from keyboard_core import press_key
from pointer_core import mouse_click, mouse_down, mouse_up
class _FakeKeyboard:
def __init__(self) -> None:
self.pressed: list[str] = []
async def press(self, key: str) -> None:
self.pressed.append(key)
class _FakeMouse:
def __init__(self) -> None:
self.events: list[tuple[object, ...]] = []
async def move(self, x: int, y: int) -> None:
self.events.append(("move", x, y))
async def down(self, *, button: str) -> None:
self.events.append(("down", button))
async def up(self, *, button: str) -> None:
self.events.append(("up", button))
async def click(self, x: int, y: int, *, button: str, click_count: int) -> None:
self.events.append(("click", x, y, button, click_count))
class _FakeLocator:
async def count(self) -> int:
return 0
class _FakePage:
def __init__(self, target: dict[str, object], js_result: object = None) -> None:
self.target = target
self.js_result = {"answer": 42} if js_result is None else js_result
self.url = "https://example.com/test"
self.viewport_size = {"width": 1280, "height": 900}
self.keyboard = _FakeKeyboard()
self.mouse = _FakeMouse()
async def evaluate(self, source: str, _arg: object = None) -> object:
if "document.activeElement" in source:
return self.target
encoded = json.dumps(self.js_result)
return {"ok": True, "result_json": encoded, "result_bytes": len(encoded.encode("utf-8"))}
def locator(self, _selector: str) -> _FakeLocator:
return _FakeLocator()
class _FakeSession:
def __init__(self, page: _FakePage) -> None:
self.session_id = "session-1"
self.page = page
self.lock = asyncio.Lock()
class _FakeManager:
def __init__(self, page: _FakePage) -> None:
self.session = _FakeSession(page)
async def get(self, _owner: str, _session_id: str, *, touch: bool = False) -> _FakeSession:
return self.session
async def revalidate_locked_session(self, _owner: str, _session_id: str, _session: _FakeSession) -> None:
return None
async def _sync_page(self, session: _FakeSession) -> _FakePage:
return session.page
def _target(*, tag: str, type: str = "", role: str = "", label: str = "", content_editable: bool = False) -> dict[str, object]:
return {
"present": True,
"tag": tag,
"type": type,
"role": role,
"label": label,
"autocomplete": "",
"content_editable": content_editable,
}
def test_enter_is_available_for_search_but_not_generic_text_input() -> None:
async def exercise() -> None:
search_page = _FakePage(_target(tag="input", type="search", label="Search"))
search_result = await press_key(_FakeManager(search_page), "owner", "session-1", "Enter")
assert search_result["status"] == "BROWSER_KEY_PRESSED"
assert search_page.keyboard.pressed == ["Enter"]
text_page = _FakePage(_target(tag="input", type="text", label="Message"))
with pytest.raises(BrowserBridgeError) as raised:
await press_key(_FakeManager(text_page), "owner", "session-1", "Enter")
assert raised.value.code == "KEY_ENTER_TARGET_BLOCKED"
asyncio.run(exercise())
def test_javascript_requires_action_confirmation_and_redacts_secret_api_path() -> None:
async def exercise() -> None:
page = _FakePage(_target(tag="textarea", label="Note"))
manager = _FakeManager(page)
with pytest.raises(BrowserBridgeError) as unconfirmed:
await run_javascript(manager, "owner", "session-1", "return { answer: 42 };", user_confirmed_javascript_action=False)
assert unconfirmed.value.code == "JAVASCRIPT_ACTION_CONFIRMATION_REQUIRED"
with pytest.raises(BrowserBridgeError) as secret:
await run_javascript(manager, "owner", "session-1", "return document.cookie;", user_confirmed_javascript_action=True)
assert secret.value.code == "JAVASCRIPT_SECRET_OR_NETWORK_API_BLOCKED"
result = await run_javascript(manager, "owner", "session-1", "return { answer: 42 };", user_confirmed_javascript_action=True)
assert result["status"] == "BROWSER_JAVASCRIPT_COMPLETED"
assert result["result"] == {"answer": 42}
assert result["user_edge_profile_used"] is False
asyncio.run(exercise())
def test_raw_canvas_pointer_no_longer_needs_repeated_confirmation() -> None:
async def exercise() -> None:
page = _FakePage(_target(tag="canvas", label="Chart"))
manager = _FakeManager(page)
clicked = await mouse_click(manager, "owner", "session-1", 100, 80)
assert clicked["status"] == "BROWSER_POINTER_CLICKED"
assert page.mouse.events == [("click", 100, 80, "left", 1)]
await mouse_down(manager, "owner", "session-1")
await mouse_up(manager, "owner", "session-1")
assert page.mouse.events[-2:] == [("down", "left"), ("up", "left")]
asyncio.run(exercise())
|