How to scroll the page to the very bottom in Android Espresso? - android

I need to check the presence of the button that is located below. To do this, scroll through the page
#Test
public void checkMoneyBackButton() throws Exception {
onView(withId(R.id.btnAuthLogin)).perform(click());
Thread.sleep(10000);
onView(withId(R.id.etSessionKey1)).perform(typeText("1234"));
closeSoftKeyboard();
SystemClock.sleep(45000);
ViewInteraction viewInteraction = Espresso.onView(withText("**** 0431"));
viewInteraction.perform(click());
Thread.sleep(3000);
onView(withId(R.id.cardContainer))
.perform(swipeUp());
onView(withId(R.id.statementMoneyBack)).check(matches(isDisplayed()));
}
But using this code, I get an error:
Error performing 'fast swipe' on view 'with id:...

Hacky style, but should do the trick:
`` // Scroll down the view with for loop (as many times you need to iterate)
for(int i=0;i<=20;i++){
onView(withText("Use_here_any_text_from_the_view")).perform(swipeUp());
}
``

Add Barista into your Espresso and use this command. Barista will help you for some action in your automation (Especially if your background is not engineering like me).
scrollTo(R.id.far_away_widget);
scrollTo(R.string.text);
scrollTo("A widget with this text");

Related

Espresso testing ProgressBar that toggles quickly

I have an activity that fires an asynchronous request to a server.
Right when it is fired, I show a progress bar. When a result is returned to the activity, I set the progressbar to View.GONE.
I have two tests right now.
One for testing trying to login with wrong credentials
which works perfectly :
#Test
public void tryLogin__withWrongPassword() {
onView(withId(R.id.loginEmail))
.perform(typeText("em#ail.com"), closeSoftKeyboard());
onView(withId(R.id.loginPassword))
.perform(typeText("123456789"), closeSoftKeyboard());
onView(withId(R.id.loginSubmit))
.perform(click());
onView(withId(R.id.loginProgressBar))
.check(matches(isDisplayed()));
onView(isRoot()).perform(waitFor(3000));
onView(withId(R.id.loginProgressBar))
.check(matches(not((isDisplayed()))));
onView(withId(R.id.loginPassword))
.check(matches(hasErrorText("Wrong password")));
}
And one that I test with no internet connectivity that does not work :
#Test
public void tryLogin__withoutInternet() {
onView(withId(R.id.loginEmail))
.perform(typeText("em#ail.com"), closeSoftKeyboard());
onView(withId(R.id.loginPassword))
.perform(typeText("123456789"), closeSoftKeyboard());
onView(withId(R.id.loginSubmit))
.perform(click());
onView(withId(R.id.loginProgressBar))
.check(matches(isDisplayed()));
onView(isRoot()).perform(waitFor(3000));
onView(withId(R.id.loginProgressBar))
.check(matches(not((isDisplayed()))));
onView(withText("Network error, try again later"))
.inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView())))
.check(matches(isDisplayed()));
}
The test fails because the progressbar in this case is shown for a fraction of a second (because the error is almost immediately dispatched from the viewmodel)
and seemingly Espresso cannot catch it while it is still loading.
My question is how could this potentially be fixed in my test? I have read somewhere that Espresso cannot test progress bars and the advice was to use UIAutomator instead, however I just started with Instrumented tests and chose Espresso and it is difficult for me to find the ideal tool for this case. Moreover, it seems to be working just fine when the progressbar appears for a bit more than half a second (in my first test for example)
P.S. the waitFor(long millis) method is a utility add-on method I made to force Espresso to wait for a specified amount of time before checking something (enforcing a timeout as a quality requirement)
Edit for clarification :
My main question here is if anyone has an idea why the visibility is not caught when it is active for less than an amount of time vs when it lasts for more than half a second, even if the check is done immediately after the perform(click()) call.

Appium android button click not working?

Tried the login use case with appium for android native app. But button click not working. But I am getting all test passed.Tried with mobile driver also.
#BeforeClass
public static void setUp() throws MalformedURLException
{
DesiredCapabilities capabilities=new DesiredCapabilities();
capabilities.setCapability("BROWSER_NAME","Chrome");
capabilities.setCapability("VERSION","4.3");
capabilities.setCapability("deviceName","SGH-T999L");
capabilities.setCapability("platformName","Android");
capabilities.setCapability("appPackage","org.odk.collect.android");
capabilities.setCapability("appActivity","com.fieldforce.android.activities.LoginActivity");
webDriver=new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
// webDriver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);
}
#Test
public void testLogin() throws Exception
{
// webDriver.switchTo().window("NATIVE_APP");
WebDriverWait wait = new WebDriverWait(webDriver, 10);
WebElement userName= webDriver.findElement(By.id("txt_username"));
userName.sendKeys("733894");
WebElement password= webDriver.findElement(By.id("txt_password"));
password.sendKeys("Pass#123");
WebElement login_button= webDriver.findElement(By.id("org.odk.collect.android:id/btn_login"));
wait.until(ExpectedConditions.visibilityOf(login_button));
login_button.click();
}
#AfterClass
public static void tearDown()
{
webDriver.quit();
}
Of course the test will pass, as you are just trying to click on Login Button, it doesn't matter for your test case whether it should pass or fail unless you add some Assert after clicking on login button.
Try adding some wait after click on login
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
And then try asserting something in #test for method testLogin like add below two statement in the end, and make them compatible with locator you get after login
Actualtext = driver.findElement(By.xpath("locator to verify after login")).getText();
Assert.assertEquals(Actualtext, "assert Text");
I got the same issue.
Please make sure your submit button(UI) is not covered by the phone keyboard.
If it covers, Solution :
hide the keyboard before run the click [.click()] function.
keyboard hide code is here How to dismiss the keyboard in appium using Java?
Reason:
Coz Appium clicks the button using x&y UI coordinates and if the keyboard covers the submit button it clicks on the keyboard not on the button.
In my case I've also tried similar button clicking with no result. I've realized that I wasn't clicking the right element.
To verify what I was clicking I've printed element's Text and TagName:
List<MobileElement> views = driver.findElements(By.className ("android.widget.TextView"));
System.out.println("1: "+views.get(2).getText());
System.out.println("2: "+views.get(2).getTagName());
views.get(2).click();
Output was:
1: OK
2: android.widget.TextView
My classNames I got through UI Automator Viewer, Android/Sdk/tools/bin/uiautomatorviewer application.
Although, before list's getting you could temporarily use Thread.sleep(5000); with your own values to check assumption about slow element loading and replace it with proper time waiting method if required in case of time problem.
Sometimes a button could have multilayer structure and it is required to get the right layer you could click. In my case there were two layers.
Would suggest using
WebElement login_button= webDriver.findElement(By.id("btn_login")); //as used for other WebElement
Also i believe a general login page shall ideally be having the login visible, if that not be the case, you might want to perform a scroll down on the page instead of
wait.until(ExpectedConditions.visibilityOf(login_button));
PS - If you are receiving any error/exception post this. Please add to the question and let know.
As your keyboard hiding the Login button, so hide the keyboard by,
driver.hidekeyboard();

Robolectric-2.3 testing animation

I'm writing test to my project with Robolectric-2.3.
I'd like to test my UI properties such as Views visibility. The actions of showing/hiding views are wrapped into Animations. How to test it ?
I tried to use ShadowSystemClock.sleep() method to wait until animation ends but it doesn't seem to work as I expected.
#Test
public void testHideSearch() throws Exception {
mListFragment.hideSearch(); //<--- animation launched here
sleep(1000);
View searchEditText = mListFragment.getView().findViewById(R.id.filterEditText);
assertFalse(searchEditText.getVisibility() == View.VISIBLE);
}
What is the correct approach to the issue ?
Try using this instead of sleep:
Robolectric.getUiThreadScheduler.advanceBy(1000);
If you use Animator's your approach should work, but if you use Animations, you'll need to use ShadowAnimation instead. Assuming the actual visibility of your view is changed in onAnimationEnd(), something like the following should work:
ShadowAnimation animation = Robolectric.shadowOf(searchEditText.getAnimation());
animation.invokeEnd();

Adjusting the scrollview at the bottom of the page

I have lots of contents on one page so i am using scrollview. I have one scan button at the bottom of the page, which i need to click many times to scan lots of barcodes. when i click on scan button, i am opening "BarcodeScanner" application that will sacn the barcode and returns the result to my application. so when i come back to my application, again i need to scroll the entire page to click the scan button which is at the bottom side. So is there any way to initialize the scroll at the bottom of the page? Please help
Thanks in advance
How do you think that you can initialise the scroll view.!! If you have lots of contents in a page you have to use scroll view for seeing all the contents. ! Try this, put your scroll view xml code in to botom of the xml code. and check.!!
Say your ScrollView id is scrollId, the code will lokk like this
scrollView = (ScrollView) findViewById (R.id.scrollId);
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
Try this
s.post(new Runnable() {
public void run() {
s.scrollTo(0, mScrollView.getBottom());
// or this
//s.fullScroll(s.FOCUS_DOWN);
}
});

Android. How can I slide NavigationDrawer from Espresso test library?

I create unit-test from Espresso in Android. My project has NavigationDrawer. I create test which must slide NavigationDrawer and click on button. In understand, how create slide action in my test.
My current solution:
try
{
runTestOnUiThread(new Runnable()
{
#Override
public void run()
{
DrawerLayout drawer = (DrawerLayout)getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.LEFT);
}
});
}
catch (Throwable e)
{
e.printStackTrace();
}
But I think it's bad code.
There is a description how to do this in android-test-kit group, explained by ValeraZakharov - link.
Espresso 1.1 has now been out for a little while, but I've still been completely unable to find any Navigation Drawer functionality within it... That is, until I found out that this functionality is actually included within a totally separate library file: espresso-contrib, which is available via gradle with
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'
This is super briefly mentioned on the "Why Espresso" page of the Espresso website:
If you need any functionality from the contrib library, such as DrawerActions, copy the espresso-contrib jar from here.
Here's the DrawerActions documentation. And here is some sample code that uses it. Hopefully that puts you in the right direction; the EspressoSamples page has no example code for this...
openDrawer() was deprecated, you can use this code instead.
I can confirm it works
onView(withId(R.id.my_drawer_layout)).perform(DrawerActions.open());
NavigationDrawer support is coming soon in the next release of Espresso. For the time being, you can implement your own ViewAction, where you would add the code inside your Runnable. This is an incomplete solution because you will likely experience timing issues related to opening/closing of the drawer. Espresso 1.1 will take care of this.

Categories

Resources