In this demo, we will start writing our Appium Test cases using our page object classes.
We will start by creating our test base, so we don't need to repeat all the desired capabilities in each test case, as we noticed in the previous examples in the previous chapters.
So, we will start with the test base and then we will start creating our task classes.
As we noticed in the previous examples, we edit the desired capabilities for each test class.
But in our project here, if we are using page objects, we will use the same concepts from the page base with the test base.
We will share all desired capabilities once we edit them in the test base and then, we will extend all the test classes from this test base.
So, we need to add desired capabilities once, and then after that, it will be used in all the test cases.
So under the test
folder and the java
folder, we will create a new class and name it TestBase
.
Inside this TestBase
, we will add our Appium driver, and then we will add two functions, one for the Android setup, and one for the iOS setup with the required desired capabilities.
So, here I added two different static voids, one for Android setup and one for iOS setup.
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.ios.IOSDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.MalformedURLException;
import java.net.URL;
public class TestBase {
public static AppiumDriver driver;
public static void Android_setUp() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("platformVersion", "9.0");
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("app",
System.getProperty("user.dir") + "/apps/ToDo.apk");
driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), capabilities);
}
public static void iOS_setUp() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "iOS");
capabilities.setCapability("platformVersion", "14.4");
capabilities.setCapability("deviceName", "iPhone 11 Pro");
capabilities.setCapability("app",
System.getProperty("user.dir") + "/apps/DailyCheck.zip");
driver = new IOSDriver(new URL("http://localhost:4723/wd/hub"), capabilities);
}
public static void tearDown() {
if (null != driver) {
driver.quit();
}
}
}
In each test case, we will call the setup if it's for Android or if it's for iOS.
Here, I added the desired capabilities and you can change the platform name, the device name, and the application is the application that we have here in our app
folder.
This is for iOS and also, you can change the device name as you want and this is the user directory for the DailyCheck to-do application.
We are using IOSDriver
and AndroidDriver
.
Also, we have the tearDown
, which is also called in each test class.
We will start with the Android test case, and create a new test class.
I will create a new Java class ToDo_Android
and the first step is I need to extend from TestBase
to be able to add the Android set up and use the driver in my test case.
Then I need to use the page object, so I will start adding CreateTaskPage createTaskPage
as a new object, and then we will add TasksListPage tasksListPage
.
After that, we can add our test case with the annotation @Test
, and then public void test_add_ask()
to add a new test.
Then we can call the Android setup.
How can we call this Android setup?
Because it's a public static void
, we can call it directly from TestBase
but we need to add an exception for handling this one because it's including the URL for the driver.
Then with tasksListPage
, we can create a new TasksListPage
and we are passing in driver
since driver
is also inside the TestBase
.
The driver is based on the setup that we added here, so for example, we added Android_setUp()
so this will give us the AndroidDriver and start using it with the Android application.
We added the tasksListPage
, and then we have to add createTaskPage = new CreateTaskPage()
, and we need to pass it a driver
.
This driver
will go to the PageBase
and start removing this one with the actual class and start collecting the elements from the page classes with annotations @AndroidFindBy
or @iOSXCUITFindBy
.
Now we have created two objects, and then we can call tasksListPage.clickAddTaskBtn()
.
This is the first one, and then with createTaskPage
, we need to add the task name and add the task description.
So we will add enterTaskName()
, and with the task name, I can add "Finish Appium Course", for example.
With createTaskPage
we can also enterTaskDesc()
with "Finishing my course ASAP", for example.
Then we need to click on the save button, so we will call createTaskPage.clickSaveBtn()
.
import org.testng.annotations.Test;
import java.net.MalformedURLException;
public class ToDo_Android extends TestBase {
CreateTaskPage createTaskPage ;
TasksListPage tasksListPage;
@Test
public void test_add_task() throws MalformedURLException {
Android_setUp();
tasksListPage = new TasksListPage(driver);
createTaskPage = new CreateTaskPage(driver);
tasksListPage.clickAddTaskBtn();
createTaskPage.enterTaskName("Finish Appium Course");
createTaskPage.enterTaskDesc("Finishing my course ASAP");
createTaskPage.clickSaveBtn();
}
}
This is simple, as we are now using the page object classes and using the Android set up, and then we are just calling the methods from the page object and just passing the values from here.
Now let's run our Android test and check the test results - this is the first time running this one with the page object.
Here we have the Android emulator and this is the Appium server.
Now we are installing the to-do application, sending the application to the device, and then opening the application and continuing with the rest of the commands.
The application is opened, we will click to create a new one, add a task and finish.
So we added it and saved it, and our test case passed successfully.
But, here we will notice that the keyboard is still open.
Maybe if we are using data-driven, for example, and we need to open the application in the next iteration with a different task name, we will face an issue because this keyboard hides the "+" button.
So, after we add the task description and click the save button, maybe we need to close this keypad.
Here in our code, maybe after we enter the description, we can call driver.hideKeyboard()
, so the driver will close the keyboard and then we can click save.
After that, maybe we can call the tearDown()
to close the driver.
import org.testng.annotations.Test;
import java.net.MalformedURLException;
public class ToDo_Android extends TestBase {
CreateTaskPage createTaskPage ;
TasksListPage tasksListPage;
@Test
public void test_add_task() throws MalformedURLException {
Android_setUp();
tasksListPage = new TasksListPage(driver);
createTaskPage = new CreateTaskPage(driver);
tasksListPage.clickAddTaskBtn();
createTaskPage.enterTaskName("Finish Appium Course");
createTaskPage.enterTaskDesc("Finishing my course ASAP");
driver.hideKeyboard();
createTaskPage.clickSaveBtn();
tearDown();
}
}
Let's run again with hideKeyboard()
and then we can check - for now, we'll just close it manually, because if we ran our test it would fail since it can't find the "+" button.
So, now our application is opened, we add a new task and description, hide the keyboard and then click Save.
Our test case passed and we also hid the keyboard.
So if we open the similar we don't have the keyboard, so every time it will be hidden after we add the task description.
Why don't we have the tasks that we added before?
Because every time in the TestBase
we are installing the application for the first time.
If you wanted to use the application with the previous data, we can just remove the app
and use the appPackage
and appActivity
and also you can use the setCapability
with "noReset", so you will not clear the data from the application to continue with a task list that you added before.
Quiz
The quiz for this chapter can be found in Chapter 7.5