2017年7月9日 星期日

UIautomator 綜合演練





情況1. settings>開啟wifi
情況2. settings>display>設定sleep time
情況3. settings>sound>調整ringtone音量大小
情況4. phone>輸入*#06# 查詢IMEI
情況5. message>新增訊息>新增附件(開啟相機拍照)>寄出
情況6. settings>about phone > 開啟 developer options > 再進入 developer options >開啟pointer location


@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    // 初始化/實例化(重要)
    protected UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    @Test
    public void testCase_1() throws IOException, UiObjectNotFoundException {
        //情況1. settings>開啟wifi

        // Launch Settings
        uiDevice.executeShellCommand("am start -n com.android.settings/.Settings");

        // Scroll to WLAN and click
        UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
        uiScrollable.scrollTextIntoView("WLAN");
        uiDevice.findObject(new UiSelector().text("WLAN")).clickAndWaitForNewWindow();

        // 判斷開關 如果與想要的狀態不同則點擊
         UiObject uiObject=uiDevice.findObject(new UiSelector().resourceId("com.android.settings:id/switch_widget"));
        if (uiObject.isChecked() == false) {
            uiObject.click();
        }
    }

    @Test
    public void testCase_2() throws IOException, UiObjectNotFoundException {
        //情況2. settings>display>設定sleep time

        // Launch Settings
        uiDevice.executeShellCommand("am start -n com.android.settings/.Settings");

        // Scroll to Display and click
        UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
        uiScrollable.scrollTextIntoView("Display");
        uiDevice.findObject(new UiSelector().text("Display")).clickAndWaitForNewWindow();

        // Scrool to Sleep and select mode
        uiScrollable.scrollTextIntoView("Sleep");
        uiDevice.findObject(new UiSelector().text("Sleep")).clickAndWaitForNewWindow();
        uiDevice.findObject(new UiSelector().text("10 minutes")).clickAndWaitForNewWindow();
    }

    @Test
    public void testCase_3() throws IOException, UiObjectNotFoundException {
        //情況3. settings>sound>調整ringtone音量大小

         // Launch Settings
        uiDevice.executeShellCommand("am start -n com.android.settings/.Settings");

        // Scroll to Display and click
        UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
        uiScrollable.scrollTextIntoView("Sound");
        uiDevice.findObject(new UiSelector().text("Sound")).clickAndWaitForNewWindow();

        // Ringtone 屬於第2Bar 取得界限依照給定百分比拉動(40%)
         Rect rect=uiDevice.findObject(new UiSelector().resourceId("android:id/seekbar")).getBounds();
        uiDevice.swipe(rect.left,rect.centerY(),(int)(rect.left+rect.width()*40/100),rect.centerY(),20);
    }

    @Test
    public void testCase_4() throws IOException, UiObjectNotFoundException {
        //情況4. phone>輸入*#06# 查詢IMEI

        // Launch Phone
        uiDevice.executeShellCommand("am start -n com.android.contacts/.activities.DialtactsActivity");

        // 點擊輸入欄位且輸入內容
         uiDevice.findObject(new UiSelector().resourceId("com.android.contacts:id/digits")).clickAndWaitForNewWindow();
        setStrings("*#06#");
        uiDevice.findObject(new UiSelector().resourceId("com.android.contacts:id/dialButton")).clickAndWaitForNewWindow();
    }

    @Test
    public void testCase_5() throws IOException, UiObjectNotFoundException {
        //情況5. message>新增訊息>新增附件(開啟相機拍照)>寄出

         // Launch Message
        uiDevice.executeShellCommand("am start -n com.android.mms/.ui.traditional.MessageLaunchActivity");

        // 新增訊息按鈕
         uiDevice.findObject(new UiSelector().resourceId("com.android.mms:id/fab_1")).clickAndWaitForNewWindow();

        // 輸入電話
         setStrings("0123456789");

        // 新增附件
         uiDevice.findObject(new UiSelector().description("Attach")).clickAndWaitForNewWindow();
        uiDevice.findObject(new UiSelector().text("Capture picture")).clickAndWaitForNewWindow();
        uiDevice.findObject(new UiSelector().description("Shutter")).clickAndWaitForNewWindow();
        uiDevice.findObject(new UiSelector().description("Attach done button")).clickAndWaitForNewWindow();

        //寄出
         uiDevice.findObject(new UiSelector().resourceId("com.android.mms:id/send_button_mms")).clickAndWaitForNewWindow();
    }

    @Test
    public void testCase_6() throws IOException, UiObjectNotFoundException, InterruptedException {
        //情況6. settings>about phone > 開啟 developer options > 再進入 developer options >開啟pointer location

        // Launch Settings
        uiDevice.executeShellCommand("am start -n com.android.settings/.Settings");

        // Scroll to About phone and click
        UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
        uiScrollable.scrollTextIntoView("About phone");
        uiDevice.findObject(new UiSelector().text("About phone")).clickAndWaitForNewWindow();

        // Scroll to Build number and click 8 times
        UiObject uiobject;
        uiScrollable.scrollIntoView(uiobject=uiDevice.findObject(new UiSelector().text("Build number")));
        for (int i = 0; i < 8; i++) {
            uiobject.click();
        }
        Thread.sleep(2*1000);
        uiDevice.pressBack();

        // Scroll to Developer options and click
        uiScrollable.scrollIntoView(uiobject=uiDevice.findObject(new UiSelector().text("Developer options")));
        uiobject.click();

        // 滾動至有Pointer location的畫面 (因為找到時剛好在最下方 被虛擬鍵擋住 所以往下找一個選項 讓目標找到時能比較上來一些)
        uiScrollable.scrollIntoView(uiobject = uiDevice.findObject(new UiSelector().text("Show surface updates")));

        // 因為要使用Uiobject2 所以要等待久一點 以防系統瞬間抓取會失效
         Thread.sleep(5 * 1000);

        // 由於滾動至目標畫面時的CheckButton數量不固定(所以不能利用第N個來尋找) 所以要先蒐集有相同屬性的上層再判斷下層是否有目標的字樣 最後才能抓取目標以便判斷
         List<UiObject2> list = uiDevice.findObjects(By.clazz("android.widget.LinearLayout"));
        for (UiObject2 ui : list) {
            if (ui.hasObject(By.clazz("android.widget.RelativeLayout"))) {
                UiObject2 ui2 = ui.findObject(By.clazz("android.widget.RelativeLayout"));
                if (ui2.hasObject(By.text("Pointer location"))) {
                    UiObject2 ui3 = ui.findObject(By.res("android:id/widget_frame")).findObject(By.res("android:id/switch_widget"));
                    if (ui3.isChecked() == false) {
                        ui3.click();
                        return;
                    }
                }
            }
        }
    }

    public void setStrings(String text) {
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            if (c >= 48 && c <= 57) //0~9
                uiDevice.pressKeyCode(c - 41);
            else if (c >= 65 && c <= 90) //A~Z
                uiDevice.pressKeyCode(c - 36, 1);
            else if (c >= 97 && c < 122) //a~z
                uiDevice.pressKeyCode(c - 68);
            else if (c == 42) // *
                uiDevice.pressKeyCode(KEYCODE_STAR);
            else if (c == 35) // #
                uiDevice.pressKeyCode(KEYCODE_POUND);
            else if (c == 46) // .
                uiDevice.pressKeyCode(KEYCODE_PERIOD);
            else if (c == 47) // /
                uiDevice.pressKeyCode(KEYCODE_SLASH);
            else if (c == 58)  // :
                uiDevice.pressKeyCode(KEYCODE_SEMICOLON);
            else if (c== 64) // @
                uiDevice.pressKeyCode(KEYCODE_AT);
            else if(c==32) // space
                uiDevice.pressKeyCode(KEYCODE_SPACE);
        }
    }
    
}



情況1:


情況2:


情況3: 


情況4:


情況5:


情況6:




PS.
大部分情況建議使用 UiSelector/clickAndWaitForNewWindow 會比 BySelector/click 好一些
前者都會有默認的等待時間 後者是立即性的執行(如果當下沒有抓到就會失敗)
雖然執行速度是後者較快 但實際情況設備都會需要一點時間更新畫面 前者會更適用