Loading tests/src/com/android/launcher3/util/rule/FailureWatcher.java +41 −31 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ package com.android.launcher3.util.rule; import static androidx.test.InstrumentationRegistry.getInstrumentation; import android.os.FileUtils; import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.util.Log; import androidx.test.uiautomator.UiDevice; Loading @@ -12,9 +14,12 @@ import com.android.launcher3.ui.AbstractLauncherUiTest; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class FailureWatcher extends TestWatcher { private static final String TAG = "FailureWatcher"; Loading @@ -26,20 +31,6 @@ public class FailureWatcher extends TestWatcher { mLauncher = launcher; } private static void dumpViewHierarchy(UiDevice device) { final ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { device.dumpWindowHierarchy(stream); stream.flush(); stream.close(); for (String line : stream.toString().split("\\r?\\n")) { Log.e(TAG, line.trim()); } } catch (IOException e) { Log.e(TAG, "error dumping XML to logcat", e); } } @Override protected void succeeded(Description description) { super.succeeded(description); Loading @@ -53,22 +44,41 @@ public class FailureWatcher extends TestWatcher { public static void onError(UiDevice device, Description description, Throwable e) { if (device == null) return; final String pathname = getInstrumentation().getTargetContext(). getFilesDir().getPath() + "/TestScreenshot-" + description.getMethodName() + ".png"; Log.e(TAG, "Failed test " + description.getMethodName() + ", screenshot will be saved to " + pathname + ", track trace is below, UI object dump is further below:\n" + Log.getStackTraceString(e)); dumpViewHierarchy(device); try { final String dumpsysResult = device.executeShellCommand( "dumpsys activity service TouchInteractionService"); Log.d(TAG, "TouchInteractionService: " + dumpsysResult); } catch (IOException ex) { final File parentFile = getInstrumentation().getTargetContext().getFilesDir(); final File sceenshot = new File(parentFile, "TestScreenshot-" + description.getMethodName() + ".png"); final File hierarchy = new File(parentFile, "Hierarchy-" + description.getMethodName() + ".zip"); // Dump window hierarchy try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(hierarchy))) { out.putNextEntry(new ZipEntry("bugreport.txt")); dumpStringCommand("dumpsys window windows", out); dumpStringCommand("dumpsys package", out); dumpStringCommand("dumpsys activity service TouchInteractionService", out); out.closeEntry(); out.putNextEntry(new ZipEntry("visible_windows.zip")); dumpCommand("cmd window dump-visible-window-views", out); out.closeEntry(); } catch (IOException ex) { } Log.e(TAG, "Failed test " + description.getMethodName() + ",\nscreenshot will be saved to " + sceenshot + ",\nUI dump at: " + hierarchy + " (use go/web-hv to open the dump file)", e); device.takeScreenshot(sceenshot); } device.takeScreenshot(new File(pathname)); private static void dumpStringCommand(String cmd, OutputStream out) throws IOException { out.write(("\n\n" + cmd + "\n").getBytes()); dumpCommand(cmd, out); } private static void dumpCommand(String cmd, OutputStream out) throws IOException { try (AutoCloseInputStream in = new AutoCloseInputStream(getInstrumentation() .getUiAutomation().executeShellCommand(cmd))) { FileUtils.copy(in, out); } } } Loading
tests/src/com/android/launcher3/util/rule/FailureWatcher.java +41 −31 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ package com.android.launcher3.util.rule; import static androidx.test.InstrumentationRegistry.getInstrumentation; import android.os.FileUtils; import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.util.Log; import androidx.test.uiautomator.UiDevice; Loading @@ -12,9 +14,12 @@ import com.android.launcher3.ui.AbstractLauncherUiTest; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class FailureWatcher extends TestWatcher { private static final String TAG = "FailureWatcher"; Loading @@ -26,20 +31,6 @@ public class FailureWatcher extends TestWatcher { mLauncher = launcher; } private static void dumpViewHierarchy(UiDevice device) { final ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { device.dumpWindowHierarchy(stream); stream.flush(); stream.close(); for (String line : stream.toString().split("\\r?\\n")) { Log.e(TAG, line.trim()); } } catch (IOException e) { Log.e(TAG, "error dumping XML to logcat", e); } } @Override protected void succeeded(Description description) { super.succeeded(description); Loading @@ -53,22 +44,41 @@ public class FailureWatcher extends TestWatcher { public static void onError(UiDevice device, Description description, Throwable e) { if (device == null) return; final String pathname = getInstrumentation().getTargetContext(). getFilesDir().getPath() + "/TestScreenshot-" + description.getMethodName() + ".png"; Log.e(TAG, "Failed test " + description.getMethodName() + ", screenshot will be saved to " + pathname + ", track trace is below, UI object dump is further below:\n" + Log.getStackTraceString(e)); dumpViewHierarchy(device); try { final String dumpsysResult = device.executeShellCommand( "dumpsys activity service TouchInteractionService"); Log.d(TAG, "TouchInteractionService: " + dumpsysResult); } catch (IOException ex) { final File parentFile = getInstrumentation().getTargetContext().getFilesDir(); final File sceenshot = new File(parentFile, "TestScreenshot-" + description.getMethodName() + ".png"); final File hierarchy = new File(parentFile, "Hierarchy-" + description.getMethodName() + ".zip"); // Dump window hierarchy try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(hierarchy))) { out.putNextEntry(new ZipEntry("bugreport.txt")); dumpStringCommand("dumpsys window windows", out); dumpStringCommand("dumpsys package", out); dumpStringCommand("dumpsys activity service TouchInteractionService", out); out.closeEntry(); out.putNextEntry(new ZipEntry("visible_windows.zip")); dumpCommand("cmd window dump-visible-window-views", out); out.closeEntry(); } catch (IOException ex) { } Log.e(TAG, "Failed test " + description.getMethodName() + ",\nscreenshot will be saved to " + sceenshot + ",\nUI dump at: " + hierarchy + " (use go/web-hv to open the dump file)", e); device.takeScreenshot(sceenshot); } device.takeScreenshot(new File(pathname)); private static void dumpStringCommand(String cmd, OutputStream out) throws IOException { out.write(("\n\n" + cmd + "\n").getBytes()); dumpCommand(cmd, out); } private static void dumpCommand(String cmd, OutputStream out) throws IOException { try (AutoCloseInputStream in = new AutoCloseInputStream(getInstrumentation() .getUiAutomation().executeShellCommand(cmd))) { FileUtils.copy(in, out); } } }