"""Tests for devices mixin (list, use, current, info, reboot, logcat).""" import pytest from tests.conftest import fail, ok class TestDevicesList: async def test_parse_devices(self, server): server.run_adb.return_value = ok( stdout=( "List of devices attached\n" "ABC123\tdevice\tmodel:Pixel_6 product:oriole\n" "10.20.0.25:5555\tdevice\tmodel:K2401 product:K2401\n" ) ) devices = await server.devices_list() assert len(devices) == 2 assert devices[0].device_id == "ABC123" assert devices[0].model == "Pixel_6" assert devices[1].device_id == "10.20.0.25:5555" async def test_empty(self, server): server.run_adb.return_value = ok(stdout="List of devices attached\n") devices = await server.devices_list() assert len(devices) == 0 async def test_failure(self, server): server.run_adb.return_value = fail("adb not found") devices = await server.devices_list() assert len(devices) == 0 class TestDevicesUse: async def test_select_device(self, server): server.run_adb.return_value = ok( stdout="List of devices attached\nABC123\tdevice\n" ) result = await server.devices_use("ABC123") assert result["success"] is True assert server.get_current_device() == "ABC123" async def test_not_found(self, server): server.run_adb.return_value = ok( stdout="List of devices attached\nOTHER\tdevice\n" ) result = await server.devices_use("MISSING") assert result["success"] is False assert "not found" in result["error"] async def test_offline_device(self, server): server.run_adb.return_value = ok( stdout="List of devices attached\nABC123\toffline\n" ) result = await server.devices_use("ABC123") assert result["success"] is False assert "offline" in result["error"] class TestDevicesCurrent: async def test_no_device_set(self, server): server.run_adb.return_value = ok(stdout="List of devices attached\n") result = await server.devices_current() assert result["device"] is None async def test_auto_detect_single(self, server): server.run_adb.return_value = ok( stdout="List of devices attached\nABC123\tdevice\n" ) result = await server.devices_current() assert result.get("available") is not None async def test_device_set(self, server): # Pre-populate cache and set device server.run_adb.return_value = ok( stdout="List of devices attached\nABC123\tdevice\tmodel:Pixel\n" ) await server.devices_list() server.set_current_device("ABC123") result = await server.devices_current() assert result["device"]["device_id"] == "ABC123" class TestDeviceInfo: async def test_full_info(self, server): battery = ( "Current Battery Service state:\n level: 85\n status: 2\n plugged: 2" ) df_out = ( "Filesystem 1K-blocks Used Available\n" "/data 64000000 32000000 32000000" ) server.run_shell_args.side_effect = [ ok(stdout=battery), ok(stdout="10: wlan0 inet 192.168.1.100/24"), ok(stdout="mWifiInfo SSID: MyNetwork, BSSID: ..."), ok(stdout=df_out), ] server.get_device_property.side_effect = lambda p, d=None: { "ro.build.version.release": "14", "ro.build.version.sdk": "34", "ro.product.model": "Pixel 6", "ro.product.manufacturer": "Google", "ro.product.device": "oriole", }.get(p) result = await server.device_info() assert result["success"] is True assert result["battery"]["level"] == 85 assert result["ip_address"] == "192.168.1.100" assert result["wifi_ssid"] == "MyNetwork" assert result["model"] == "Pixel 6" async def test_device_offline(self, server): server.run_shell_args.return_value = fail("device offline") result = await server.device_info() assert result["success"] is False class TestDeviceReboot: @pytest.mark.usefixtures("_dev_mode") async def test_reboot(self, server, ctx): ctx.set_elicit("accept", "Yes, reboot now") server.run_adb.return_value = ok() result = await server.device_reboot(ctx) assert result["success"] is True assert result["mode"] == "normal" @pytest.mark.usefixtures("_dev_mode") async def test_reboot_recovery(self, server, ctx): ctx.set_elicit("accept", "Yes, reboot now") server.run_adb.return_value = ok() result = await server.device_reboot(ctx, mode="recovery") assert result["mode"] == "recovery" @pytest.mark.usefixtures("_dev_mode") async def test_cancelled(self, server, ctx): ctx.set_elicit("accept", "Cancel") result = await server.device_reboot(ctx) assert result["success"] is False assert result.get("cancelled") is True @pytest.mark.usefixtures("_no_dev_mode") async def test_requires_dev_mode(self, server, ctx): result = await server.device_reboot(ctx) assert result["success"] is False class TestLogcat: @pytest.mark.usefixtures("_dev_mode") async def test_capture(self, server): logline = "01-01 00:00:00.000 I/TAG: message" server.run_shell_args.return_value = ok(stdout=logline) result = await server.logcat_capture() assert result["success"] is True assert result["output"].startswith("01-01") @pytest.mark.usefixtures("_dev_mode") async def test_with_filter(self, server): server.run_shell_args.return_value = ok(stdout="filtered output") result = await server.logcat_capture(filter_spec="MyApp:D *:S") assert result["filter"] == "MyApp:D *:S" @pytest.mark.usefixtures("_dev_mode") async def test_clear_first(self, server): server.run_shell_args.side_effect = [ok(), ok(stdout="fresh logs")] result = await server.logcat_capture(clear_first=True) assert result["success"] is True assert server.run_shell_args.call_count == 2 @pytest.mark.usefixtures("_no_dev_mode") async def test_requires_dev_mode(self, server): result = await server.logcat_capture() assert result["success"] is False @pytest.mark.usefixtures("_dev_mode") async def test_logcat_clear(self, server): server.run_shell_args.return_value = ok() result = await server.logcat_clear() assert result["success"] is True assert result["action"] == "logcat_clear"