From the course: Advanced Appium

Simulating phone calls and SMS - Appium Tutorial

From the course: Advanced Appium

Start my 1-month free trial

Simulating phone calls and SMS

- [Instructor] Mobile devices are phones, after all, so it's important to be able to test how our apps behave when we receive a phone call or a text. The Appium phone call API allows you to trigger a fake incoming call, to accept the call, or to cancel the call. This is great for ensuring your app behaves properly during phone usage. However, it does have some limitations. It is Android only, and the methods we'll look at only work on emulators, not real devices. To trigger a phone call on a real device, you'd need to have a sim card in it and use some kind of telephony service to make the call during your test. Let's see how to actually use the phone call API. All the available functionality is embedded within a single command, driver.makeGsmCall. This command takes a phone number as the first parameter. And this number should be a string with only numbers, no dashes. The second parameter is the type of action we want to have happen on the device. There are three: call, accept, and cancel. Call triggers the incoming call, accept causes the phone to accept it, and cancel causes the device to end the call; and that's it. What about SMS? Some apps use SMS as part of the app functionality. For example, when you try to log in to an app, the app's backend might trigger an SMS message to the phone with a security code as part of a two-factor authentication scheme. Apps can then read the incoming message, verify the code, and log the user in, all without requiring the user to manually enter anything. Unfortunately, we have no way, using Appium alone, to read the text of incoming SMS messages. Text messages show up on the screen in such a way that they're invisible to the regular UI. If we need to read the text of an unknown message, we would have to navigate to the messages app and read it from the UI there. As with phone calls, this API is Android only and emulator only. Let's take a look at how to use it. Basically, we just call the command driver.sendSMS. As before, the first parameter is the phone number from which to receive the message. The second parameter is the message itself that we want to send, and this is how the message looks when it's sent. Okay, let's turn to our emulator and our code editor and put these APIs into action. Okay, what we're going to do in our test here is just accept and then end a phone call while using our app to make sure our app doesn't do anything weird. Then we're going to open this little view of our app, the verify phone number view. As you can see, when this view pops up, we're requested to confirm SMS read permissions for the app. Once we do that, this view just sits here doing nothing until an SMS comes in with the correct code as its message body. So our test will actually send that message body, then check to see that this view updated when the message was received. Okay, let's head back to our editor. I'm going to open up chapter three five phone SMS before .java; let's check it out. We've got a lot of the same boilerplate as earlier, but this time for starting an Android test, of course. A couple new constants have been added for us at the top. On line 14, we're defining the phone number we want to send these fake calls and messages from. Just below that, I'm defining a few locators for working with the SMS verification functionality in this app. First, the element that we need to click to get to the verification screen, then the text label we need to find to know that we're waiting for verification, this xpath selector here and, finally, the text label that contains the magic string verified, which will only show up when the correct code is sent via SMS. This is what we'll need to do to prove that our app was able to read the SMS that we've triggered from Appium. There's one more change we need to make to our boilerplate, which is the addition of a new capability called autoGrantPermissions. So let's add this capability. This autoGrantPermissions capability causes Appium to read the app's manifest file to see what permissions might be requested and has the emulator automatically grant those permissions to the app before launch so that we are not bothered by permissions pop-ups along the way, the way that we were when we were using the app manually. We just set this capability to true to tell Appium to do this for us. Now let's fill out our test code itself down inside the testPhoneAndSMS function on line 43. First, let's create for ourselves a WebDriverWait object called wait, which we'll use further down as we wait and interact with different elements. So we'll initialize this as a new WebDriverWait object, pass in our driver object, and say that we want to wait for up to five seconds to find these different elements. Now let's get to the login screen where we'll have an input box we can interact with during a phone call. So we'll say driver.findElementByAccessibilityId login screen, and we'll click on this element to get to the login screen. And now let's make a phone call to the device using driver.makeGsmCall and we'll pass in the phone number as the first parameter and the action as our second parameter. In this case, we want the call action to trigger the call. After that, we'll wait for two seconds, just so we can watch the phone ring for a bit. Of course, this means we'll need to register our potential exception, which is an interrupted exception. Next, let's accept the call using the same driver.makeGsmCall method and passing in the same phone number, but this time using the except action rather than the call action. And while we're on the call, we'll do something with our application to make sure that it still works correctly while a phone call is in progress. So, we'll just find a text field by its accessibility ID. I happen to know there's one by the name of username, and we'll send some text to this field and, again, have another pause just for effect so that the phone call can continue for a little bit. Now that we've satisfied ourselves that the app is working, even in the middle of a phone call, we can end the call using the cancel action. So we write driver.MakeGsmCall, our same phone number, and the action we want should be cancel. Now, let's go back to the home screen by using driver.navigate().back in preparation for the SMS portion of our test. Next, let's wait for our navigation item to appear. The button that we need to click to get into the verification screen. So we'll say wait.until and here we'll use an expected condition, presence of element located by, and we pass in our verify screen locator. Once it's found, we click on the element; and now we want to get to the verification view and wait for something on the verification view to know that we are actually there. So we're again going to wait for the presence of an element, but this one will be the SMS waiting element to prove that we have got to the verification view and we're waiting for an SMS with the correct code to be sent. Now we need to actually send the correct code, so we'll use driver.sendSMS. We'll send it from our original phone number, and we need to make sure that the correct code shows up somewhere here in the string which will become the message body. So we'll just say, "Your code is 123456" which is the magic code that this app is waiting for. And then, of course, we need to verify that the code was accepted, so we need to wait for another element. This time we're going to wait for the SMS verified element, which we defined up top. This should be all we need to verify that the SMS code has been accepted by the application and the user automatically logged in as a result. Okay, let's run this code and watch it in action. We've got our Android emulator, and I'll pull up the Appium server logs and the Appium server will start the test application on the emulator. We can see the incoming call, that it was accepted, some actions took place, and we saw that the SMS message was sent and the app actually verified the SMS message. It all happened pretty quickly, so to double check, let's just go back to IntelliJ and notice that, in fact, our test did pass. So, that's how we work with phone and SMS on Android using Appium.

Contents