Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple UI Automator tests. #7

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: macos-latest

steps:
- uses: actions/[email protected]
Expand All @@ -21,7 +21,14 @@ jobs:
distribution: 'zulu'
java-version: 8

- run: ./gradlew build
- run: ./gradlew build assembleAndroidTest

- name: Run Tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 24
# The tests require the sample to be installed.
script: ./gradlew installDebug connectedCheck

- run: ./gradlew uploadArchives
if: ${{ github.ref == 'refs/heads/trunk' && github.repository == 'JakeWharton/ProcessPhoenix' }}
Expand Down
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ allprojects {
}

ext {
minSdkVersion = 11
minSdkVersion = 14
compileSdkVersion = 30

androidxTestRunner = 'androidx.test:runner:1.3.0'
androidxTestRules = 'androidx.test:rules:1.3.0'
androidxTestUiAutomator = 'androidx.test.uiautomator:uiautomator:2.2.0'
}
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ POM_LICENCE_DIST=repo

POM_DEVELOPER_ID=jakewharton
POM_DEVELOPER_NAME=Jake Wharton

android.useAndroidX=true
android.enableJetifier=false
7 changes: 7 additions & 0 deletions process-phoenix/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
apply plugin: 'com.android.library'

dependencies {
androidTestImplementation rootProject.ext.androidxTestRunner
androidTestImplementation rootProject.ext.androidxTestRules
androidTestImplementation rootProject.ext.androidxTestUiAutomator
}

android {
compileSdkVersion rootProject.ext.compileSdkVersion

defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

compileOptions {
Expand Down
15 changes: 15 additions & 0 deletions process-phoenix/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.jakewharton.processphoenix"
>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<!-- TODO http://b.android.com/179651 -->
<uses-sdk
android:minSdkVersion="18"
tools:overrideLibrary="android_libs.ub_uiautomator"
/>
<application/>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.jakewharton.processphoenix;

import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.PowerManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Context.POWER_SERVICE;
import static android.content.Intent.CATEGORY_LAUNCHER;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP;
import static android.os.PowerManager.FULL_WAKE_LOCK;
import static android.os.PowerManager.ON_AFTER_RELEASE;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

@RunWith(AndroidJUnit4.class)
public final class ProcessPhoenixTest {
private static final String PROCESS_ID = "Process ID: ";
private static final String EXTRA_TEXT = "Extra Text: ";
private static final String TARGET_PACKAGE = "com.jakewharton.processphoenix.sample";

private final Context context = InstrumentationRegistry.getTargetContext();
private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
private final UiDevice device = UiDevice.getInstance(instrumentation);

private PowerManager.WakeLock wakeLock;

@Before public void launchSample() {
// Wake up the screen.
PowerManager power = (PowerManager) context.getSystemService(POWER_SERVICE);
wakeLock = power.newWakeLock(FULL_WAKE_LOCK | ACQUIRE_CAUSES_WAKEUP | ON_AFTER_RELEASE, "test");
wakeLock.acquire();

// Unlock the device so that the tests can input keystrokes.
KeyguardManager keyguard = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);
keyguard.newKeyguardLock("test").disableKeyguard();

// Launch the sample app.
PackageManager pm = context.getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(TARGET_PACKAGE);
if (intent == null) {
throw new AssertionError("ProcessPhoenix Sample not installed.");
}
intent.addCategory(CATEGORY_LAUNCHER);
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
waitForWindow();
}

private void waitForWindow() {
assertTrue(device.waitForWindowUpdate(TARGET_PACKAGE, SECONDS.toMillis(15)));
}

@After public void tearDown() {
wakeLock.release();
}

@Test public void triggerRebirthCreatesNewProcess() throws UiObjectNotFoundException {
UiObject originalObject = device.findObject(new UiSelector().textStartsWith(PROCESS_ID));
int originalId = Integer.parseInt(originalObject.getText().substring(PROCESS_ID.length()));

device.findObject(new UiSelector().text("Restart Process")).click();
waitForWindow();

UiObject newObject = device.findObject(new UiSelector().textStartsWith(PROCESS_ID));
int newId = Integer.parseInt(newObject.getText().substring(PROCESS_ID.length()));

assertNotEquals(originalId, newId);
}

@Test public void triggerRebirthWithIntentCreatesNewProcessUsingIntent()
throws UiObjectNotFoundException {
UiObject originalObject = device.findObject(new UiSelector().textStartsWith(PROCESS_ID));
int originalId = Integer.parseInt(originalObject.getText().substring(PROCESS_ID.length()));

device.findObject(new UiSelector().text("Restart Process with Intent")).click();
waitForWindow();

UiObject newObject = device.findObject(new UiSelector().textStartsWith(PROCESS_ID));
int newId = Integer.parseInt(newObject.getText().substring(PROCESS_ID.length()));

assertNotEquals(originalId, newId);

UiObject extraObject = device.findObject(new UiSelector().textStartsWith(EXTRA_TEXT));
String extraText = extraObject.getText().substring(EXTRA_TEXT.length());

assertEquals("Hello!", extraText);
}
}