diff options
Diffstat (limited to 'examples/ex4_uiautomator/src/main')
-rw-r--r-- | examples/ex4_uiautomator/src/main/AndroidManifest.xml | 19 | ||||
-rw-r--r-- | examples/ex4_uiautomator/src/main/java/com/google/android/mobly/snippet/example4/UiAutomatorSnippet.java | 111 |
2 files changed, 130 insertions, 0 deletions
diff --git a/examples/ex4_uiautomator/src/main/AndroidManifest.xml b/examples/ex4_uiautomator/src/main/AndroidManifest.xml new file mode 100644 index 0000000..89d5276 --- /dev/null +++ b/examples/ex4_uiautomator/src/main/AndroidManifest.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.mobly.snippet.example4"> + + <application android:allowBackup="false"> + <meta-data + android:name="mobly-snippets" + android:value="com.google.android.mobly.snippet.example4.UiAutomatorSnippet" /> + </application> + + <!-- This snippet does NOT target ex2 (which is the main app the code + automates). The instrumentation target is itself which creates a + standalone snippet. --> + <instrumentation + android:name="com.google.android.mobly.snippet.SnippetRunner" + android:targetPackage="com.google.android.mobly.snippet.example4" /> + +</manifest> diff --git a/examples/ex4_uiautomator/src/main/java/com/google/android/mobly/snippet/example4/UiAutomatorSnippet.java b/examples/ex4_uiautomator/src/main/java/com/google/android/mobly/snippet/example4/UiAutomatorSnippet.java new file mode 100644 index 0000000..9fc01b2 --- /dev/null +++ b/examples/ex4_uiautomator/src/main/java/com/google/android/mobly/snippet/example4/UiAutomatorSnippet.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.android.mobly.snippet.example4; + +import static org.junit.Assert.assertEquals; + +import android.content.Context; +import android.content.Intent; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.UiDevice; +import androidx.test.uiautomator.UiObject2; +import androidx.test.uiautomator.Until; +import com.google.android.mobly.snippet.Snippet; +import com.google.android.mobly.snippet.rpc.Rpc; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; + +/** + * Demonstrates how to drive an app using UIAutomator without access to the app's source code or + * classpath. + * + * <p>Drives the Espresso example app from ex2 without instrumenting it. + */ +public class UiAutomatorSnippet implements Snippet { + private static final class UiAutomatorSnippetException extends Exception { + private static final long serialVersionUID = 1; + + public UiAutomatorSnippetException(String message) { + super(message); + } + } + + private static final String MAIN_PACKAGE = "com.google.android.mobly.snippet.example2"; + private static final int LAUNCH_TIMEOUT = 5000; + + private final Context mContext; + private final UiDevice mDevice; + + public UiAutomatorSnippet() { + mContext = InstrumentationRegistry.getInstrumentation().getContext(); + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + } + + @Rpc(description="Opens the main activity of the app") + public void startMainActivity() throws UiAutomatorSnippetException { + // Send the launch intent + Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(MAIN_PACKAGE); + if (intent == null) { + throw new UiAutomatorSnippetException( + "Unable to create launch intent for " + MAIN_PACKAGE + "; is the app installed?"); + } + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + mContext.startActivity(intent); + + // Wait for the app to appear + mDevice.wait(Until.hasObject(By.pkg(MAIN_PACKAGE).depth(0)), LAUNCH_TIMEOUT); + } + + @Rpc(description="Pushes the main app button, and checks the label if this is the first time.") + public void pushMainButton(boolean checkFirstRun) { + if (checkFirstRun) { + assertEquals( + "Hello World!", + // Example of finding object by id. + mDevice.findObject(By.res(MAIN_PACKAGE, "main_text_view")).getText()); + } + // Example of finding a button by text. Finding by ID is also possible, as above. + UiObject2 button = mDevice.findObject(By.text("PUSH THE BUTTON!")); + button.click(); + if (checkFirstRun) { + assertEquals( + "Button pressed 1 times", + mDevice.findObject(By.res(MAIN_PACKAGE, "main_text_view")).getText()); + } + } + + @Rpc(description="Perform a UIAutomator dump") + public String uiautomatorDump() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + mDevice.dumpWindowHierarchy(baos); + byte[] dumpBytes = baos.toByteArray(); + String dumpStr = new String(dumpBytes, Charset.forName("UTF-8")); + return dumpStr; + } finally { + baos.close(); + } + } + + @Override + public void shutdown() throws IOException { + mDevice.executeShellCommand("am force-stop " + MAIN_PACKAGE); + } +} |