Monday 29 February 2016

How to do Horizontal Scroll in Appium?



In the previous post we have seen that how to perform vertical scroll in Appium and now it is turn to learn horizontal scroll in Appium.Now many apps has horizontal tab scroll and testing that seems challenging first but with this post you will be able to write appium test case very efficiently. We will use ToucAction class and driver.swipe() method to achieve desired result.

App Under Test-
Consider that you have a app with 15 Horizontal Tabs named as tab1,tab2,tab3 and so on till tab15

Test Case Scenario-
1. Launch the app
2. perform right to left tab till we can see tab8.
3. click on tab8.

Finding Y-Coordinate -
We need y co-ordinates of the screen  and to find that there are two ways -
1. Using Pointer Location-
    * Go to phones Settings
    * Click on Developer Options
    * Enable Pointer Location 
    * open your app and click on the mid of the horizontal tab and then you will get x and y
       coordinates but note down y- coordinates.

2. Using UI automator - 
   *Open UIAutomator Inspector.
   * Take screen shot.
   * Click on middle of the horizontal tab and note down y-coordinates displayed at top right corner.

Test Case -
1. We will implement horizontalScroll() method. In this method we will get the screen size with that we can find our start point on right side and end point on left side as we are going for right to left swipe. We also have y co-ordinates so we can use driver.swipe() to perform horizontal scroll as shown below
2. We are using for loop to scroll till we find the expected tab.

public class HorizontalTabscroll
{
    AppiumDriver driver;
    Dimension size; 
    @Before
    public void testCaseSetup()throws  Exception
    {

        DesiredCapabilities cap=new DesiredCapabilities();
        cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
        cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "4000");
        cap.setCapability(MobileCapabilityType.APP, "c://apks//seekbarsample.apk");
        cap.setCapability("noReset", true);
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap);

    }
  
    @Test
    public void testHorizontalScroll()throws Exception
    {
        for(int i=0;i<4;i++)
        {
            Thread.sleep(2000);
            if (driver.findElement(By.name("tab8")).isDisplayed())
            {
                driver.findElement(By.name("tab8")).click();
                break;
            }
            else
            {
                horizontalScroll();
            }

        }
    }
    public void horizontalScroll()
    {
        size=driver.manage().window().getSize();
        int x_start=(int)(size.width*0.60);
        int x_end=(int)(size.width*0.30);
        int y=130;
        driver.swipe(x_start,y,x_end,y,4000);
    }
    @After
    public void testCaseTearDown()
    {
        driver.quit();
    }
}

Note - The same test case can be used for Vertical Scroll using start_y and end_y and x value will be constant (Try this out).

With help of this tutorial you can write appium test code for right to left horzontal scroll/swipe , left to right horzontal scroll/swipe , horizontal scroll until you find matching element.

I hope you find this tutorial useful. Do share your feedback and questions in comments section below.Please follow me on social media to get latest post updates.

How to do Vertical Scroll in Appium without scrollTo()?



Hi everyone today we will see how to use scroll action in Appium Test case.As we know in latest version of appium swipe() and scrollTo() methods are depricated lets see an alternative way to scroll through as List View.

Video Tutorial - 
 

App Under Test -
Check out the below screenshot of the app which has ListView containing 50 rows . Each row contains Text and Toggle Button. When you click on the row text at the top you can check which row was clicked.
Vertical Scroll Testing with Appium
Vertical Scroll

Test Scenario-
1. Launch Activity.
2. Scroll to List item:25.
3. Click on the row text.
4. Click on the toggle button.
scroll top to bottom in Appium
Vertical Scroll


Test Case -



package com.example.anuja.appiumapplication;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.URL;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileBy;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.remote.MobileCapabilityType;

import static junit.framework.Assert.assertNotNull;

/**
 * Created by Anuja on 2/8/2017.
 */



public class HorizontalTabScroll
{
    AppiumDriver driver;
    Dimension size;

    @Before
    public void testCaseSetup()throws  Exception
    {

        DesiredCapabilities cap=new DesiredCapabilities();
        cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
        cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "4000");
        cap.setCapability(MobileCapabilityType.APP, "c://apks//listviewsample.apk");
        cap.setCapability("noReset", true);
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap);

    }
    
    @Test
    public void testScroll()throws Exception
    {
        driver.findElementByAccessibilityId("Views").click();
        AndroidElement list = (AndroidElement) driver.findElement(By.id("android:id/mobile_list"));
        MobileElement listGroup = list
                .findElement(MobileBy
                        .AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("
                                + "new UiSelector().text(\" List item:25\"));"));
        assertNotNull(listGroup.getLocation());
        listGroup.click();
    }

    @After
    public void testCaseTearDown()
    {
        driver.quit();
    }
}
with this post you can write test code for Vertical Scroll up to specified dimensions , Vertical Scroll till you find the element  and vertical scroll till the end.

I hope you find this tutorial useful. Do share your feedback and questions in comments section below.Please follow me on social media to get latest post updates.

Thursday 25 February 2016

Testing Camera Activity using Intent



We have seen how to use intent for inter app testing and so far we have seen how to test Dialer and Browser activity. In the post I will give you simple example for testing Camera Activity. There are many apps which uses camera to capture image and share it. Testing this scenario is now very easy with Espresso Intent.

App Under Testing -
I have created a simple app as per be below screenshot when you click on the camera it launches camera activity then you can capture the image.

Test Camera Activity with Espresso

Test Case Scenario -
1. Launch the app.
2. Take  a photo 
3. check whether the photo is taken and displayed in Image View box.

Test Case Code Description -
1. We need to create a Custom Matcher to check the image view contains image. So create a new Java Class in androidTest folder with name ImageViewMatcher and copy the code given below.
2. In our Test Case class we will stub the camera activity using the app launcher icon image so that we can cross check it. So the method createImageCaptureStub() we put the app drawable image in the bundle and create Intent with the bundle and then pass the same intent as ActivityResult.
3.Before Test case execute we stub the intent so when the app launches camera the drawable image will be passed as part of intend stub.
4. Then In our test case we click on camera button which calls intend and we get the drawable image which we stubbed earlier and we can assert it in our test case.
Custom Matcher -

package com.example.anuja.cameraintentsample;

/**
 * Created by Anuja on 24-02-2016.
 */
import android.support.test.espresso.matcher.BoundedMatcher;
import android.view.View;
import android.widget.ImageView;

import org.hamcrest.Description;
public class ImageViewMatcher {

    public static BoundedMatcher<View, ImageView> hasDrawable() {
        return new BoundedMatcher<View, ImageView>(ImageView.class) {
            @Override
            public void describeTo(Description description) {
                description.appendText("has drawable");
            }

            @Override
            public boolean matchesSafely(ImageView imageView) {
                return imageView.getDrawable() != null;
            }
        };
    }
}

Test Case -


package com.example.anuja.cameraintentsample;

import android.app.Activity;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.test.espresso.intent.rule.IntentsTestRule;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static android.app.Instrumentation.ActivityResult;
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.intent.Intents.intending;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

import static com.example.anuja.cameraintentsample.ImageViewMatcher.hasDrawable;
import static org.hamcrest.Matchers.not;

/**
 * Created by Anuja on 24-02-2016.
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CameraIntentTest {

        @Rule
        public IntentsTestRule<ImageViewerActivity> mIntentsRule = new IntentsTestRule<>(
                ImageViewerActivity.class);

        @Before
        public void stubCameraIntent() {
            ActivityResult result = createImageCaptureStub();

            // Stub the Intent.
            intending(hasAction(MediaStore.ACTION_IMAGE_CAPTURE)).respondWith(result);
        }

        @Test
        public void testTakePhoto() {
            // Check that the ImageView doesn't have a drawable applied.
            onView(withId(R.id.imageView)).check(matches(not(hasDrawable())));

            // Click on the button that will trigger the stubbed intent.
            onView(withId(R.id.button_take_photo)).perform(click());

            // With no user interaction, the ImageView will have a drawable.
            onView(withId(R.id.imageView)).check(matches(hasDrawable()));
        }

        private ActivityResult createImageCaptureStub() {
            // Put the drawable in a bundle.
            Bundle bundle = new Bundle();
            bundle.putParcelable(ImageViewerActivity.KEY_IMAGE_DATA, BitmapFactory.decodeResource(
                    mIntentsRule.getActivity().getResources(), R.drawable.ic_launcher));

            // Create the Intent that will include the bundle.
            Intent resultData = new Intent();
            resultData.putExtras(bundle);

            // Create the ActivityResult with the Intent.
            return new ActivityResult(Activity.RESULT_OK, resultData);
        }
    }

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)

Wednesday 24 February 2016

Espresso Intent to Test Launch of Browser Activity



In my previous post we have seen how to use Espresso Intent to test dialer activity.We know sometimes our app launches activities which are outside our app liker dialer, camera or browser etc. In this post we will learn how to test browser activity using intent.

App Under Test -
Consider you have an app with a button "Click Here". Once you click it launches chrome browser and opens url www.google.com

Test Case Scenario -
Our test case is to click on the button and check the browser activity is launched and opens the right url.

Test Case-


import android.content.Intent;
import android.support.test.espresso.intent.rule.IntentsTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.intent.Intents.intended;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData;
import static android.support.test.espresso.intent.matcher.IntentMatchers.toPackage;
import static android.support.test.espresso.intent.matcher.UriMatchers.hasHost;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.equalTo;
@RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@LargeTest
public class BrowserIntentTest {

    private static final String PACKAGE_NAME="com.android.chrome";
    @Rule
    public IntentsTestRule<MainActivity> mActivityRule = new IntentsTestRule<>(
            MainActivity.class);

    @Test
    public void test1()throws Exception
    {
            Thread.sleep(3000);
            onView(withId("Click Here")).perform(click());
            Thread.sleep(1000);
            intended(allOf(hasData(hasHost(equalTo("www.google.com"))),
                    hasAction(Intent.ACTION_VIEW),
                    toPackage(PACKAGE_NAME)));

    }
}

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)

Tuesday 16 February 2016

Testing Web Views with Appium



Now a days many apps are hybrid. Hybrid apps means app containing Web Views.  We have seen in previous post that how to perform different kinds of interaction with native android app using Appium but now it time see the how to perform web interaction on Web Views. We just have to notify the appium that we will be testing Web Views from the specific point in the test case and appium WebDriver handles it for us.Let us how to do with a simple example.

How to Inspect Web Views in Chrome Browser -

1. Go to chrome browser
2. Connect the Device with USB Debugging ON

Enable USB Debugging
Enable USB Debugging

3. Type this url -chrome://inspect/devices#devices

Chrome Inspector
Chrome inspector

4. click on any url listed on web page.

Chrome inspector console
Chrome inspector console

5. Then click on any UI element and you will get associated html source code which you can use to write your own xpath.

App under testing -


Suppose you have a app with a Web page Displaying a Login screen which displays page Title "WELCOME". The app also displays two text-boxes first to enter email id and second to enter password and there are two button "Cancel" and "Submit". After click on Submit the page shows "Successfully Logged In".

How to Switch To Web Views - 


Check out the code sample given below which switched to web view and then test cases perform actions mentioned in your code on directly on the Web Views.

  // Switch to WebView
        Set<String> contextNames = driver.getContextHandles();
        System.out.println(contextNames.size());
        for (String contextName : contextNames) {
            System.out.println(contextName);
            if (contextName.contains("WEBVIEW")){
                driver.context(contextName);
            }


Test Scenario-


1. First test that title "WELCOME" is displayed.

2.Test that two text-boxes are displayed and two buttons are also displayed.

3. Enter email is and password.

4. click on Submit

5. Test Success Message is displayed.

Appium Test Case-

@Test
public void testWebViews()throws Exception
    {
        // Switch to WebView
        Set<String> contextNames = driver.getContextHandles();
        System.out.println(contextNames.size());
        for (String contextName : contextNames) {
            System.out.println(contextName);
            if (contextName.contains("WEBVIEW")){
                driver.context(contextName);
            }
        }
        // check WELCOME text is present
       Assert.assertEquals("WELCOME", driver.findElement(By.id("welcome_text")).getText());
        //Check UI elements text boxes and buttons are present on the page
        Assert.assertTrue(driver.findElementById("email_edit").isDisplayed());
        Assert.assertTrue(driver.findElementById("password_edit").isDisplayed());
        Assert.assertTrue(driver.findElementById("cancel_button").isDisplayed());
        Assert.assertTrue(driver.findElementById("submit_button").isDisplayed());

        //enter email id and password
        driver.findElementById("email_edit").sendKeys("anujabhatt88@gmail.com");
        driver.findElementById("password_edit").sendKeys("12345");

        // /click on submit button
        driver.findElementById("submit_button").click();

        //Explicit wait for submission
        Thread.sleep(3000);
        //Check for successful submission
        Assert.assertEquals("Successfully Logged In",driver.findElementById("display_text"));
    }

Now you can start testing web views in Appium :-)
If you find this post helpful then pleas share your feedback in comments section below. Do follow me on social media for latest post updates. Thanks :-)

Testing WebViews using Espresso Web



Testing app with Web Views is now possible with Espresso Web. Espresso allows various Web Interactions which we can use to construct our test cases. locating UI element for Web Views is different as UIAutomator cannot detect the Web UI element hence we will use Chrome inspector to locate the UI element which I have already explained here.

In this post I will cover frequently used web iterations so that you can immediately start writing test cases for Web views.Web view test cases takes little more time as we need to add explicit wait because loading of web page depends on the internet connection.

Video Tutorial -



App under testing -
Suppose you have a app with a Web page Displaying a Login screen which displays page Title "WELCOME". The app also displays two text-boxes first to enter email id and second to enter password and there are two button "Cancel" and "Submit". After click on Submit the page shows "Successfully Logged In".

Test Scenario-
1. First test that title "WELCOME" is displayed.
2.Test that two text-boxes are displayed and two buttons are also displayed.
3. Enter email is and password.
4. click on Submit
5. Test Success Message is displayed.

Test Case Example -


@RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@LargeTest
public class WebViewSample {

@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class); 

@Before
public void setUp()
{
    // enable java script for web page to perform web interactions     

      onWebView().forceJavascriptEnabled();   
}

@Test
public void testWebPage()throws Exception
{
    // check WELCOME text is present
    onWebView().withElement(findElement(Locator.ID, "welcome_text"))
   .check(webMatches(getText(), containsString("WELCOME")));
    //Check UI elements text boxes and buttons are present on the page
    onWebView().check(webContent(hasElementWithId("email_edit")));
    onWebView().check(webContent(hasElementWithId("password_edit")));
    onWebView().check(webContent(hasElementWithId("cancel_button")));
    onWebView().check(webContent(hasElementWithId("submit_button")));
    //enter email id and password
    onWebView().withElement(findElement(Locator.ID,"email_edit")).perform(clearElement()); 
    onWebView().withElement(findElement(Locator.ID,"email_edit")).perform(webKeys("anujabhatt88@gmail.com"));
    onWebView().withElement(findElement(Locator.ID,"password_edit")).perform(webKeys("12345"));
    //click on submit button
    onWebView().withElement(findElement(Locator.ID,"submit_button")).perform(webClick());
    //Explicit wait for submission
    Thread.sleep(3000);
    //Check for successful submission
    onWebView().withElement(findElement(Locator.ID, "display_text"))
   .check(webMatches(getText(), containsString("Successfully Logged In")));

}
}

I hope this post helps you find your code coverage for your test suit :)
Please Share your feedback in comments section below and follow QA Automated to get latest post update.Happy Testing :-)