"""A hint, OCR label and real editable value are different kinds of proof.""" from types import SimpleNamespace import pytest from artemis.drivers.android.hierarchy import parse_ui_hierarchy from artemis.utils.action_target import observation_anchor from artemis.utils.input_state import input_state, verify_input from artemis.utils.ui_filter import filter_ui_hierarchy from artemis.utils.visualization import format_minimal_list_with_elements @pytest.mark.parametrize( ("extra", "status"), [ ({"text": "example", "hint": "example", "showing-hint-text": "true"}, "empty"), ({"text": "example", "hint": "example"}, "unknown"), ({"text": "example", "hint": "example", "showing-hint-text": "false"}, "present"), ({"text": "", "hint": "example"}, "empty"), ({"hint": "example"}, "unknown"), ({"text": "actual"}, "present"), ], ) def test_editable_value_evidence(extra, status): evidence = input_state({"class": "android.widget.EditText", **extra}) assert evidence["input_value_state"] == status if status != "present": assert evidence["input_value"] in (None, "") def test_static_json_and_ocr_cannot_prove_input(): static = {"class": "android.widget.TextView", "text": '{"pairing":"example"}'} assert input_state(static) == {} node = { "class": "android.widget.EditText", "text": "", "hint": "example", "bounds": "[0,0][100,100]", "ocr_elements": [{"text": "example", "bounds": [0, 0, 100, 100]}], } lines, indexed, _ = format_minimal_list_with_elements([node], 100, 100) assert len(indexed) == 1 assert indexed[0]["input_value_state"] == "empty" assert "Hint:" in lines def test_filter_keeps_empty_input_and_does_not_promote_child_hint(): node = { "class": "android.widget.EditText", "editable": True, "text": "", "bounds": "[0,0][100,100]", "children": [ {"class": "android.widget.TextView", "text": "example", "bounds": "[0,0][100,100]"} ], } filtered = filter_ui_hierarchy([node]) assert filtered[0]["text"] == "" assert input_state(filtered[0])["input_value_state"] == "empty" def test_fresh_value_must_belong_to_the_actual_input(): node = { "class": "android.widget.EditText", "resource-id": "pair", "text": "actual", "focused": True, } assert verify_input([node], {"target_resource_id": "pair"}) == "present" assert verify_input([node], {"target_resource_id": "other"}) == "unknown" assert verify_input([{**node, "password": True}]) == "unknown" def test_driver_parser_keeps_showing_hint_and_empty_editable_nodes(): nodes = parse_ui_hierarchy( '' ) assert len(nodes) == 1 assert nodes[0]["input_value"] == "" assert nodes[0]["input_value_state"] == "empty" assert nodes[0]["focused"] is True def test_past_anchor_does_not_change_when_index_is_reused(): state = SimpleNamespace( latest_screenshot="before.png", indexed_elements=[{"text": "Connect", "center": [1, 2]}] ) old = observation_anchor(state) state.latest_screenshot = "after.png" state.indexed_elements = [{"text": "Keyboard key", "center": [3, 4]}] assert old["target_image_name"] == "before" assert observation_anchor(state)["target_snapshot_id"] != old["target_snapshot_id"]