Use UI Automator to check if a device is commissioned on GHA instead of global var PiperOrigin-RevId: 641204508
diff --git a/ui_automator/commission_reg_test.py b/ui_automator/commission_reg_test.py index c210401..7e534db 100644 --- a/ui_automator/commission_reg_test.py +++ b/ui_automator/commission_reg_test.py
@@ -6,9 +6,6 @@ if TYPE_CHECKING: from ui_automator import ui_automator -# TODO(b/318771536): Check if a device is commissioned on GHA. -_commissioned: bool = False - class CommissionRegTest(unittest.TestCase): """Test class for running commission regression test.""" @@ -28,16 +25,12 @@ self.gha_room = gha_room def test_commission(self) -> None: - global _commissioned - _commissioned = False self.ui_automator.commission_device( self.device_name, self.pairing_code, self.gha_room ) - # TODO(b/318771536): Check if a device is commissioned on GHA. - _commissioned = True def test_decommission(self) -> None: - if not _commissioned: + if not self.ui_automator.is_device_exist(self.device_name): self.skipTest('Device was not commissioned.') self.ui_automator.decommission_device(self.device_name)
diff --git a/ui_automator/ui_automator.py b/ui_automator/ui_automator.py index 11e6924..154e3a1 100644 --- a/ui_automator/ui_automator.py +++ b/ui_automator/ui_automator.py
@@ -352,6 +352,28 @@ f' on device({self._connected_device.device_info["serial"]}).' ) from e + @get_android_device_ready + def is_device_exist(self, device_name: str) -> bool: + """Checks if the device exists on Google Home App. + + Args: + device_name: Display name of commissioned device on GHA. + + Raises: + MoblySnippetError: When running `isDeviceExist` method in snippet apk + encountered an error. + + Returns: + True if the device exists on GHA. + """ + try: + return self._connected_device.mbs.isDeviceExist(device_name) + except Exception as e: + raise errors.MoblySnippetError( + f'Unable to check if {device_name} exists on GHA' + f' on device({self._connected_device.device_info["serial"]}).' + ) from e + def run_regression_tests( self, repeat: int | None,
diff --git a/ui_automator/ui_automator_test.py b/ui_automator/ui_automator_test.py index 4a1f9ff..378577c 100644 --- a/ui_automator/ui_automator_test.py +++ b/ui_automator/ui_automator_test.py
@@ -697,8 +697,12 @@ @mock.patch.object( ui_automator.UIAutomator, 'decommission_device', autospec=True ) + @mock.patch.object( + ui_automator.UIAutomator, 'is_device_exist', autospec=True + ) def test_run_regression_tests_executes_for_given_number_of_times_with_failure( self, + mock_is_device_exist, mock_decommission_device, mock_commission_device, mock_get_all_instances, @@ -713,6 +717,7 @@ None, None, ] + mock_is_device_exist.side_effect = [True, True, False, True, True] mock_get_all_instances.return_value = [self.mock_android_device] with self.assertLogs() as cm: @@ -725,6 +730,7 @@ ) self.assertEqual(mock_commission_device.call_count, 5) + self.assertEqual(mock_is_device_exist.call_count, 5) self.assertEqual(mock_decommission_device.call_count, 4) self.assertEqual( cm.output[0], 'INFO:root:Start running regression tests 5 times.' @@ -752,8 +758,12 @@ @mock.patch.object( ui_automator.UIAutomator, 'decommission_device', autospec=True ) + @mock.patch.object( + ui_automator.UIAutomator, 'is_device_exist', autospec=True + ) def test_run_regression_tests_runs_continuously_until_keyboard_interrupts( self, + mock_is_device_exist, mock_decommission_device, mock_commission_device, mock_get_all_instances, @@ -769,7 +779,9 @@ None, KeyboardInterrupt(), ] + mock_is_device_exist.side_effect = [True, False, True, False, True] mock_get_all_instances.return_value = [self.mock_android_device] + with self.assertLogs() as cm: self.ui_automator.run_regression_tests( None, @@ -781,6 +793,7 @@ self.assertEqual(mock_commission_device.call_count, 6) self.assertEqual(mock_decommission_device.call_count, 3) + self.assertEqual(mock_is_device_exist.call_count, 5) self.assertEqual( cm.output[0], 'INFO:root:Start running regression tests continuously.' ) @@ -800,8 +813,12 @@ @mock.patch.object( ui_automator.UIAutomator, 'decommission_device', autospec=True ) + @mock.patch.object( + ui_automator.UIAutomator, 'is_device_exist', autospec=True + ) def test_run_calls_run_regression_tests_and_produces_summary_in_txt( self, + mock_is_device_exist, mock_decommission_device, mock_commission_device, mock_get_all_instances, @@ -822,6 +839,7 @@ None, fake_error, ] + mock_is_device_exist.side_effect = [False, True, True] mock_get_all_instances.return_value = [self.mock_android_device] mock_open.side_effect = [io.StringIO(), txt_stream] # mock_time called by startTestRun, startTest, stopTest, and stopTestRun. @@ -855,6 +873,7 @@ ui_automator.run() self.assertEqual(mock_commission_device.call_count, 3) + self.assertEqual(mock_is_device_exist.call_count, 3) self.assertEqual(mock_decommission_device.call_count, 2) self.assertEqual( expected_summary + '\n\n' + expected_test_case_result, @@ -876,8 +895,12 @@ @mock.patch.object( ui_automator.UIAutomator, 'decommission_device', autospec=True ) + @mock.patch.object( + ui_automator.UIAutomator, 'is_device_exist', autospec=True + ) def test_run_calls_run_regression_tests_and_produces_summary_in_xml( self, + mock_is_device_exist, mock_decommission_device, mock_commission_device, mock_get_all_instances, @@ -894,6 +917,7 @@ None, None, ] + mock_is_device_exist.side_effect = [False, True, True] mock_decommission_device.side_effect = [ None, fake_error, @@ -986,6 +1010,7 @@ ui_automator.run() self.assertEqual(mock_commission_device.call_count, 3) + self.assertEqual(mock_is_device_exist.call_count, 3) self.assertEqual(mock_decommission_device.call_count, 2) (testcases,) = re.search( expected_test_suite_re, xml_stream.getvalue() @@ -1163,5 +1188,46 @@ mock_load_snippet.assert_called_once() self.assertDictEqual(report_info, {}) + @mock.patch.object(android_device, 'get_all_instances', autospec=True) + def test_is_device_exist_returns_true_when_device_exists( + self, mock_get_all_instances + ): + mock_get_all_instances.return_value = [self.mock_android_device] + self.mock_android_device.mbs.isDeviceExist.return_value = True + + self.assertTrue( + self.ui_automator.is_device_exist(_FAKE_MATTER_DEVICE_NAME) + ) + + @mock.patch.object(android_device, 'get_all_instances', autospec=True) + def test_is_device_exist_returns_false_when_device_does_not_exist( + self, mock_get_all_instances + ): + mock_get_all_instances.return_value = [self.mock_android_device] + self.mock_android_device.mbs.isDeviceExist.return_value = False + + self.assertFalse( + self.ui_automator.is_device_exist(_FAKE_MATTER_DEVICE_NAME) + ) + + @mock.patch.object(android_device, 'get_all_instances', autospec=True) + def test_is_device_exist_throws_an_error_when_snippet_method_throws_an_error( + self, mock_get_all_instances + ): + mock_get_all_instances.return_value = [self.mock_android_device] + self.mock_android_device.mbs.isDeviceExist.side_effect = Exception( + 'fake-error' + ) + + with self.assertRaises(errors.MoblySnippetError) as exc: + self.ui_automator.is_device_exist(_FAKE_MATTER_DEVICE_NAME) + + expected_error_message = ( + f'Unable to check if {_FAKE_MATTER_DEVICE_NAME} exists on GHA' + f' on device({self.mock_android_device.device_info["serial"]}).' + ) + self.assertEqual(expected_error_message, str(exc.exception)) + + if __name__ == '__main__': unittest.main()