Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UiAutomator picking app to test from app drawer

I'm trying to write an UI automated 'black box' test for an android application (I have the apk but not the source code) using UiAutomator. I'm having trouble opening the app for the drawer during the set-up phase. So far my code is

@Override
public void setUp() throws Exception {
    super.setUp();
    mDevice = UiDevice.getInstance(getInstrumentation());
    mDevice.pressHome();
    //Wait for the app drawer icon to show up on the screen
    mDevice.wait(Until.hasObject(By.desc("Apps")), 3000);
    //Obtain reference to the app drawer button in order to click it
    UiObject drawerIcon = mDevice.findObject(new UiSelector().description("Apps"));
    drawerIcon.clickAndWaitForNewWindow();
    //Finding and Clicking on the Sunshine app
    UiObject drawer = mDevice.findObject(new UiSelector().resourceId("com.sec.android.app.launcher:id/apps_grid"));
    UiObject appToTest = mDevice.findObject(new UiSelector().description("app-to-test-description"));
    while (!appToTest.exists()) {
        drawer.swipeLeft(3);
    }
    appToTest.clickAndWaitForNewWindow();
}

When I run the test it should open the app (then run the varius testing methods that I have yet to write.) Instead it opens the drawer and it hangs. I guess there is a better way to identify the drawer and scroll it until the right application is found. Here is the error log.

Running tests
Test running started
android.support.test.uiautomator.UiObjectNotFoundException: UiSelector[RESOURCE_ID=com.sec.android.app.launcher:id/apps_grid] at android.support.test.uiautomator.UiObject.getVisibleBounds(UiObject.java:891) at android.support.test.uiautomator.UiObject.swipeLeft(UiObject.java:315) at com.crisanti.roberto.uturistautomatedtest.UiAutomatorTest.setUp(UiAutomatorTest.java:29) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)

like image 370
Crysis85 Avatar asked Jan 07 '23 18:01

Crysis85


2 Answers

If you really want to start it from the menu you already answered your own question. However bear in mind that in different devices the apps drawer may be different (Samsung and others usually do their own on top of Android's).

As an alternative you can

Context context = InstrumentationRegistry.getInstrumentation().getContext(); //gets the context based on the instrumentation
Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageNameOfYourApp);  //sets the intent to start your app
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);  //clear out any previous task, i.e., make sure it starts on the initial screen
context.startActivity(intent);  //starts the app

The package name you can have by using UiAutomatorViewer (in sdk-folder/tools/).

If you want you can wait until the app is actually started by doing this (I assume you already have a UiDevice device).

device.wait(Until.hasObject(By.pkg(packageNameOfYourApp)), timeOut); //ofc you need to set timeout

This will work for any device/emulator configuration.

like image 97
Inês Avatar answered Jan 14 '23 18:01

Inês


I've figure it out how to make it works. On Lollipop the launcher is identified by "com.google.android.googlequicksearchbox:id/apps_customize_pane_content" not by "com.sec.android.app.launcher:id/apps_grid". This may be a problem since the test is dependent on the platform version (on Kitkat the launcher has another behaviour, on Marshmellow will have another different behaviour too). Another modification I've made is on the line drawer.swipeLeft(3); which I changed to drawer.swipeLeft(5);

To summarize the code to launch an application with UiAutomator on Lollipop is:

public void setUp() throws Exception {
        super.setUp();
        mDevice = UiDevice.getInstance(getInstrumentation());
        mDevice.pressHome();
        //Obtain reference to the app drawer button in order to click it
        UiObject allAppsButton = mDevice.findObject(new UiSelector().description("Apps"));
        //The operation below expects the click will result a new  window.
        allAppsButton.clickAndWaitForNewWindow();
        // Find the application in the app launcher
        UiObject appViews = mDevice.findObject(new UiSelector().resourceId("com.google.android.googlequicksearchbox:id/apps_customize_pane_content"));
        UiObject navigationDrawerApp = mDevice.findObject(new UiSelector().text("app-to-test-name"));
        while (!navigationDrawerApp.exists()){
            appViews.swipeLeft(5);
        }
        navigationDrawerApp.clickAndWaitForNewWindow();
}
like image 24
Crysis85 Avatar answered Jan 14 '23 19:01

Crysis85