Написание тестов для приложения для Android, которое входит в Facebook: UIAutomator не может заполнить текст в поле имени пользователя Facebook
Из этого вопроса / ответа мне пришла идея использовать UIAutomator для тестирования моего приложения, которое требует входа в Facebook.
Написание тестов для приложения Android, которое входит в Facebook
Я старался
UiObject2 editText = mDevice.findObject(By.clazz("android.widget.EditText"));
editText.setText("test@email.com");
Как и другие вещи, но что бы я ни делал, я не могу заставить его заполнить поле. Я использовал инструмент hierachyviewer, чтобы увидеть, что это был EditText. Это веб-просмотр, так что я не знаю.
Это возможно?
Мой полный класс тестового кода прилагается ниже:
package com.greenrobot.yesorno.test;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import com.greenrobot.yesorno.Home;
import com.greenrobot.yesorno.R;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import timber.log.Timber;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.startsWith;
/**
* Created by andytriboletti on 1/15/16.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class TestLogin {
private UiDevice mDevice;
private static final String PACKAGE_NAME = "com.greenrobot.yesorno";
private static final int LAUNCH_TIMEOUT = 5000;
@Rule
public ActivityTestRule<Home> mActivityRule = new ActivityTestRule(Home.class);
public TestLogin() {
super();
}
@Before
public void initTest() {
// Initialize UiDevice instance
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
//
// // Start from the home screen
// mDevice.pressHome();
//
// // Wait for launcher
// String launcherPackage = mDevice.getCurrentPackageName();
// mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT);
//
// // Launch the app
// Context context = InstrumentationRegistry.getContext();
// Intent intent = context.getPackageManager().getLaunchIntentForPackage(PACKAGE_NAME);
//
// // Clear out any previous instances
// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
// context.startActivity(intent);
//
// // Wait for the app to appear
// mDevice.wait(Until.hasObject(By.pkg(PACKAGE_NAME).depth(0)), LAUNCH_TIMEOUT);
}
public void fillInEmail() {
onView(withId(R.id.authButton)).perform(click());
//new UiObject(new UiSelector().description("Email or Phone")).setText("test@email.com");
//new UiObject(new UiSelector().
// boolean result = new UiObject(new UiSelector().className(android.widget.EditText.class.getName())).setText("test@email.com");
//Timber.d(result.getText());
//UiObject2 editText = new UiObject2(new UiSelector(). className("android.widget.EditText").instance(0));
//UiObject editText = new UiObject(new UiSelector().text("Email or Phone"));
UiObject2 editText = mDevice.findObject(By.clazz("android.widget.EditText"));
editText.setText("test@email.com");
SystemClock.sleep(5000);
}
@Test
public void testLogin() {
try {
onView(withId(R.id.welcome)).check(matches(isDisplayed()));
Timber.d("Logged out");
//fillInEmail();
}
catch(NoMatchingViewException e) {
onView(withId(R.id.name_age)).check(matches(isDisplayed()));
Timber.d("Not logged out");
onView(withId(R.id.slidingmenumain)).perform(actionOpenDrawer());
//SystemClock.sleep(5000);
onData(hasToString(startsWith("Logout")))
.inAdapterView(withId(android.R.id.list))
.perform(click());
//fillInEmail();
//openDrawer(R.id.drawer_layout);
//Espresso.onView(Matchers.allOf(ViewMatchers.withId(R.id.drawerItemNameTextView), ViewMatchers.hasSibling(ViewMatchers.withText(((NavDrawerItem)item).getItemName())))).perform(ViewActions.click());
}
// onView(withText("Hello world!")).check(matches(isDisplayed()));
//onView(withId(R.id.changeTextBt)).perform(click());
}
private static ViewAction actionOpenDrawer() {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(SlidingMenu.class);
}
@Override
public String getDescription() {
return "open drawer";
}
@Override
public void perform(UiController uiController, View view) {
((SlidingMenu) view).showMenu();
}
};
}
private static ViewAction actionCloseDrawer() {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(SlidingMenu.class);
}
@Override
public String getDescription() {
return "close drawer";
}
@Override
public void perform(UiController uiController, View view) {
//((SlidingMenu) view).close(GravityCompat.START);
}
};
}
}
Редактировать: я на самом деле использовал uiautomatorviewer, а не hierachyviewer. Вот скриншот, показывающий, что это текст для редактирования. По крайней мере, в соответствии с этим инструментом.
1 ответ
Я не пробовал это на странице входа в Facebook, но я смог сделать это на другой странице, которую я создал.
Я смог использовать как UIObject, так и UIObject2 для определения местоположения поля ввода в веб-форме с помощью класса EditText. Я смог установить текст в поле ввода с помощью setText(), но не смог прочитать его с помощью getText().
Выбор форм ввода HTML требует некоторой осторожности. Единственный способ надежно выбрать конкретный вход - использовать instance() для поиска n-го проиндексированного поля. Это означает, что вы, вероятно, должны ограничивать область своих поисков родительским объектом WebView (в противном случае какой-либо другой EditText на экране может сместить все).
Еще одна вещь, на которую нужно обратить внимание - это время загрузки WebView. Это не произойдет мгновенно, поэтому вам придется подождать некоторое разумное время, чтобы страница загрузилась.
Вот небольшой пример кода, который позволяет мне найти второе поле ввода на странице HTML и вставить в него текст:
UiObject input = mDevice.findObject(new UiSelector()
.instance(1)
.className(EditText.class));
input.setText("text");