From 0945dd6ba483d3ff2320dfe38cc54217e5487c95 Mon Sep 17 00:00:00 2001 From: John Richardson Date: Tue, 2 Aug 2016 16:21:47 +0100 Subject: [PATCH] Dump hierarchy view on error Dump window hierarchy view from uiautomator to a file when WA fails during execution. Note: the xml file are pre-formatted after dump. Implementation specific to android.device. --- wlauto/common/android/device.py | 12 ++++++++++++ wlauto/core/execution.py | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/wlauto/common/android/device.py b/wlauto/common/android/device.py index a269652a..c4e65382 100644 --- a/wlauto/common/android/device.py +++ b/wlauto/common/android/device.py @@ -22,6 +22,7 @@ import tempfile import shutil import threading import json +import xml.dom.minidom from subprocess import CalledProcessError from wlauto.core.extension import Parameter @@ -616,6 +617,17 @@ class AndroidDevice(BaseLinuxDevice): # pylint: disable=W0223 self.pull_file(on_device_file, filepath) self.delete_file(on_device_file) + def capture_view_hierachy(self, filepath): + """Captures the current view hierarchy into the specified file in a XML format.""" + on_device_file = self.path.join(self.working_directory, 'screen_capture.xml') + self.execute('uiautomator dump {}'.format(on_device_file)) + self.pull_file(on_device_file, filepath) + self.delete_file(on_device_file) + + parsed_xml = xml.dom.minidom.parse(filepath) + with open(filepath, 'w') as f: + f.write(parsed_xml.toprettyxml()) + def is_screen_on(self): """Returns ``True`` if the device screen is currently on, ``False`` otherwise.""" output = self.execute('dumpsys power') diff --git a/wlauto/core/execution.py b/wlauto/core/execution.py index 652816fc..659c424f 100644 --- a/wlauto/core/execution.py +++ b/wlauto/core/execution.py @@ -731,6 +731,13 @@ class Runner(object): filepath = os.path.join(settings.output_directory, filename) self.device.capture_screen(filepath) + def _take_uiautomator_dump(self, filename): + if self.context.output_directory: + filepath = os.path.join(self.context.output_directory, filename) + else: + filepath = os.path.join(settings.output_directory, filename) + self.device.capture_view_hierachy(filepath) + @contextmanager def _handle_errors(self, action, on_error_status=IterationResult.FAILED): try: @@ -746,6 +753,8 @@ class Runner(object): self.current_job.result.add_event(str(we)) try: self._take_screenshot('error.png') + if self.device.platform == 'android': + self._take_uiautomator_dump('error.xml') except Exception, e: # pylint: disable=W0703 # We're already in error state, so the fact that taking a # screenshot failed is not surprising...