feat: add configurable screenshot resolution limit
This commit is contained in:
1 parent
59f458205d
commit
ab066733b8
13 files changed
+134
-4
No files matched your search
@@ -27,6 +27,7 @@ def isolated_settings(monkeypatch, tmp_path):
|
||||
"ARTEMIS_VIDEO_ENABLED",
|
||||
"ARTEMIS_OUTPUTTER_ENABLED",
|
||||
"ARTEMIS_STEP_SUMMARIZER_ENABLED",
|
||||
"ARTEMIS_SCREENSHOT_LIMIT_ENABLED",
|
||||
]
|
||||
for key in keys:
|
||||
monkeypatch.setattr(settings, key, getattr(settings, key))
|
||||
@@ -93,21 +94,38 @@ def test_rejects_invalid_base_url(url):
|
||||
def test_capabilities_persist_and_apply_to_new_tasks(isolated_settings):
|
||||
result = service.save_capability_settings(
|
||||
service.CapabilitySettings(
|
||||
video_enabled=False, outputter_enabled=False, step_summarizer_enabled=False
|
||||
video_enabled=False,
|
||||
outputter_enabled=False,
|
||||
step_summarizer_enabled=False,
|
||||
screenshot_limit_enabled=False,
|
||||
)
|
||||
)
|
||||
assert result.video_enabled is False
|
||||
saved = dotenv_values(isolated_settings)
|
||||
assert saved["ARTEMIS_VIDEO_ENABLED"] == "false"
|
||||
assert saved["ARTEMIS_SCREENSHOT_LIMIT_ENABLED"] == "false"
|
||||
config = load_agent_config()
|
||||
assert config.video_analyzer.enabled is False
|
||||
assert config.pro.video_analyzer.enabled is False
|
||||
assert config.outputter.enabled is False
|
||||
assert config.flash.step_summarizer.enabled is False
|
||||
assert config.screenshot.enabled is False
|
||||
service.save_capability_settings(service.CapabilitySettings(video_enabled=True))
|
||||
assert load_agent_config().video_analyzer.enabled is True
|
||||
|
||||
|
||||
def test_screenshot_json_can_override_environment(monkeypatch, tmp_path):
|
||||
config_path = tmp_path / "artemis.jsonc"
|
||||
config_path.write_text(
|
||||
'{"agent": {"screenshot": {"enabled": true, "max_long_edge": 1024}}}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("ARTEMIS_SCREENSHOT_LIMIT_ENABLED", "false")
|
||||
screenshot = load_agent_config(config_path).screenshot
|
||||
assert screenshot.enabled is True
|
||||
assert screenshot.max_long_edge == 1024
|
||||
|
||||
|
||||
def test_failed_write_keeps_running_settings(monkeypatch, isolated_settings):
|
||||
previous = settings.OPENAI_MODEL
|
||||
monkeypatch.setattr(
|
||||
|
||||
@@ -15,14 +15,18 @@
|
||||
"""Unit tests for Unified Base Device Driver and implementations."""
|
||||
|
||||
import base64
|
||||
from io import BytesIO
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from artemis.drivers.base import KeyCode, ScreenData, SwipeDirection
|
||||
from artemis.drivers.mock.mock_driver import MockDeviceDriver
|
||||
from artemis.drivers.android.adb_driver import AndroidAdbDriver
|
||||
from artemis.config.agent import ScreenshotConfig
|
||||
from artemis.utils.screenshot_limit import limit_screenshot_long_edge
|
||||
|
||||
|
||||
_ONE_PIXEL_PNG = base64.b64encode(
|
||||
@@ -32,6 +36,13 @@ _ONE_PIXEL_PNG = base64.b64encode(
|
||||
).decode("ascii")
|
||||
|
||||
|
||||
def test_screenshot_limit_keeps_small_and_invalid_images_unchanged():
|
||||
small_image = base64.b64decode(_ONE_PIXEL_PNG)
|
||||
assert limit_screenshot_long_edge(small_image, 2048) is small_image
|
||||
invalid_image = b"not an image"
|
||||
assert limit_screenshot_long_edge(invalid_image, 2048) is invalid_image
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mock_driver_actions():
|
||||
"""Verify MockDeviceDriver records and performs all core actions."""
|
||||
@@ -141,6 +152,36 @@ async def test_android_driver_preserves_elements_from_combined_screen_data():
|
||||
mock_ui_client.get_hierarchy.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("enabled", [True, False])
|
||||
async def test_android_screenshot_limit_preserves_native_coordinates(enabled):
|
||||
image = Image.new("RGB", (1200, 2600), "white")
|
||||
buffer = BytesIO()
|
||||
image.save(buffer, format="JPEG")
|
||||
original = buffer.getvalue()
|
||||
elements = [{"text": "目标", "bounds": "[100,200][300,400]"}]
|
||||
ui_client = MagicMock()
|
||||
ui_client.get_screen_data.return_value = SimpleNamespace(
|
||||
base64=base64.b64encode(original).decode("ascii"),
|
||||
hierarchy_xml="<hierarchy />",
|
||||
elements=elements,
|
||||
width=1200,
|
||||
height=2600,
|
||||
)
|
||||
driver = AndroidAdbDriver("emulator-5554", MagicMock(), ui_adb_client=ui_client)
|
||||
driver._screenshot_config = ScreenshotConfig(enabled=enabled, max_long_edge=2048)
|
||||
|
||||
screen = await driver.get_screen_data(skip_settling=True)
|
||||
|
||||
with Image.open(BytesIO(screen.screenshot_bytes)) as result:
|
||||
assert result.size == ((945, 2048) if enabled else (1200, 2600))
|
||||
assert screen.width == 1200 and screen.height == 2600
|
||||
assert screen.ui_elements == elements
|
||||
assert screen.screenshot_base64 == base64.b64encode(screen.screenshot_bytes).decode("ascii")
|
||||
if not enabled:
|
||||
assert screen.screenshot_bytes == original
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_android_driver_parses_xml_hierarchy_fallback():
|
||||
"""XML-only clients remain supported without discarding their hierarchy."""
|
||||
|
||||
Reference in new issue
Block a user