Required Software Packages for Appium Automation on Mac OS

1_cDK_xkF4TfIFqAUl_ABv8w

      I observed that most of them are struggling to deal with automation for iOS in the MAC system even during the initial stage of the setup Software Package. Most of them are unaware of which package to be installed and how can be installed. The following table will help you easily configure the required software packages for automate iOS in MAC OS,

Sl. No. Software Packages What is the usage? How to install?
1 Homebrew Homebrew is a free and open-source software package management system that simplifies the installation of software on Apple’s macOS operating system 1. Open https://brew.sh/
2. Copy /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”
3. Open terminal in MAC and paste above copied command. Click enter.
2 Node Node is an open-source, cross-platform JavaScript run-time environment that executes JavaScript code outside of a browser. Here npm will get from Node. 1. Open terminal.
2. Type brew install node. Click enter
3 Appium server Appium server listen the client commands and response with actionson device side. 1. Open terminal.
2. Type npm install -g appium. Click enter
4 Appium Doctor Attempts to diagnose and fix common Node, iOS and Android configuration issues before starting Appium 1. Open terminal.
2. Type npm install -g appium-doctor. Click enter
5 Carthage It was the first dependency manager to work with Swift; in fact, Carthage itself is written in Swift! It exclusively uses dynamic frameworks instead of static libraries – this is the only way to distribute Swift binaries that are supported by iOS 8 and up. 1. Open terminal.
2. Type brew install carthage. Click enter
6 libimobiledevice In order to run our tests on real devices, we need to install libimobiledevice dependency 1. Open terminal.
2. Type brew install libimobiledevice. Click enter
7 mobiledevice mobiledevice is a command line utility for interacting with Apple’s Private Mobile Device Framework. It can be used for automating some tasks like installing and uninstalling apps on your iPhone/iPad without having to manually do it via Xcode or iTunes. You don’t need a jailbroken device! 1. Open terminal.
2. Type brew install mobiledevice. Click enter
8 Authorize-ios authorize-ios is a utility which pre-authorizes to run UIAutomation scripts on iOS devices. We need this tool for running our tests on real devices. 1. Open terminal.
2. Type npm install -g authorize-ios. Click enter
9 ios-deploy To deploy our apps to our devices by using ios-deploy. We can install and debug apps from the command line without using Xcode. 1. Open terminal.
2. Type brew install ios-deploy. Click enter
10 ideviceinstaller ideviceinstaller helps us to install, uninstall, upgrade, archive, restore and enumerate installed or archived apps. 1. Open terminal.
2. Type sudo xcode-select -r. Click enter
3. Type brew install ideviceinstaller. Click enter
11 ios_webkit_debug_proxy In order to access web views on real iOS devices, we need to install this tool. 1. Open terminal.
2. Type brew install ios-webkit-debug-proxy. Click enter
12 Maven It is used for building and managing Java-based projects by using dependencies. 1. Open terminal.
2. Type brew install maven. Click enter

     Please use all above mentioned packages prior to start scripting for iOS applications in MAC system.

make it perfect !

Automation for Mac Desktop Applications

2019-03-06 00_18_59-Window

     Appium isn’t limited to automating mobile systems! As long as there is an open way to interact with a system, a driver can be written for it, and included in Appium. Using a project called AppiumForMac. Appium can automate native macOs apps.

Setup

     Appium comes bundled with a macOs driver, but the actual AppiumForMac binary is not included, so we need to install it ourselves first:

  • Start by downloading the latest release from here.
  • Unzip the AppiumForMac.zip file by double-clicking it in Finder.
  • Move AppiumForMac.app file into your Applications folder.

     AppiumForMac uses the system Accessibility API in order to automate apps. We need to give expanded permissions to AppiumForMac in order for it to work. Here are instructions from the README:

     Open System Preferences > Security & Privacy. Click the Privacy tab. Click Accessibility in the left hand table. If needed, click the lock to make changes. If you do not see AppiumForMac.app in the list of apps, then drag it to the list from Finder. Check the checkbox next to AppiumForMac.app.

2019-03-05 23_41_47-Window

Run A Test

     Doing something different here and automate the Activity Monitor. In order to automate a macOs app, we only need to set the following desired capabilities:

{
“platformName”“Mac”,
“deviceName”“Mac”,
“app”“Activity Monitor”
}

     We specify Mac as the platform and set app to the name of the installed app we want to run. Once a test has been started, an app can also be launched using the GET command, e.g.:

driver.get(“Calculator”)

Absolute AXPath

     AppiumForMac is a little tricky, since elements can only be found using a special kind of XPath selector called “absolute AXPath”. All the AXPath selectors use Accessibility API identifiers and properties. Here included the exact rules for AXPath selectors below, but don’t be afraid if they do not make sense at first.

Here are the rules for a valid Absolute AXPath selector:

  • Uses OS X Accessibility properties, e.g. AXMenuItem or AXTitle. You cannot use any property of an element besides these.
  • Must begin with /AXApplication.
  • Must contain at least one other node following /AXApplication.
  • Does not contain “//”, or use a wildcard, or specify multiple paths using |.
  • Uses predicates with a single integer as an index, or one or more string comparisons using = and !=.
  • May use boolean operators and or or in between multiple comparisons, but may not include both and and or in a single statement. and and or must be surrounded by spaces.
  • Does not use predicate strings containing braces or parentheses ().
  • Uses single quotes, not double quotes for attribute strings.
  • Does not contain spaces except inside quotes and surrounding the and and or operators.

Any XPath selector that follows the above rules will work as absolute AXPath selector.

Be warned: if your AXPath selector breaks the rules, you won’t get a special error and instead will get an ElementNotFound exception. It can be difficult to identify whether your selectors are failing because the AXPath is invalid or the element simply is not on the screen.

The following examples as guidance:

Good examples: 

“/AXApplication[@AXTitle=’Calculator’]/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription=’clear’]”

“/AXApplication[@AXTitle=’Calculator’]/AXMenuBarItems/AXMenuBarItem[@AXTitle=’View’]/AXMenu/AXMenuItem[@AXTitle=’Scientific’]”

“/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle=’View’]/AXMenu/AXMenuItem[@AXTitle=’Basic’ and @AXMenuItemMarkChar!=”]”

Bad examples: 

“//AXButton[@AXDescription=’clear’]”
(does not begin with /AXApplication, and contains //)

“/AXApplication[@AXTitle=’Calculator’]/AXWindow[0]/AXButton[@AXDescription=’clear’]”
(not an absolute path: missing AXGroup)

“/AXApplication[@AXTitle=”Calculator“]/AXWindow[0]”
(a predicate string uses double quotes)

“/AXApplication[@AXTitle=’Calculator’]”
(path does not contain at least two nodes)

“/AXApplication[@AXTitle=’Calculator’]/AXMenuBar/AXMenuBarItems/AXMenuBarItem[@AXTitle='(Window)’]”
(a predicate string contains forbidden characters)

“/AXApplication[@AXTitle=’Calculator’]/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription =’clear’]”
(a predicate contain a space before the =)

“/AXApplication[@AXTitle=’Calculator’]/AXWindow[position()>3]/AXGroup[1]/AXButton[@AXDescription=’clear’]”
(a predicate is not a simple string or integer, and specifies more than one node)

“/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle=’View’]/AXMenu/AXMenuItem[@AXTitle=’Basic’ and@AXMenuItemMarkChar!=”]”
(leading and trailing spaces required for the boolean operator)

“/AXApplication[@AXTitle=”Calculator“]/AXWindow[0]/AXButton[@AXDescription=’clear’ and @AXEnabled=’YES’ or @AXDescription=’clear all’]”
(predicate uses multiple kinds of boolean operators; use one or more ‘and’oruse one or more ‘or’, but not both)

Tools for working with AXPath Selectors

     This special AXPath restriction is tricky to work with, but we have some tools at our disposal.

     First of all, AppiumForMac provides a tool for generating the AXPath of any element on the screen. First, launch the AppiumForMac app manually using Finder or Launchpad. It won’t display a window, but will appear in the dock. If you hold the fn key on your keyboard down for about three seconds, AppiumForMac will find the AXPath string to select whichever element your mouse pointer is currently hovering over. It stores the AXPath selector into your clipboard, so you can paste it into your test code. You’ll know when it has worked because the AppiumForMac icon jumps out of the dock.

    This behavior will work anywhere on your screen, because AppiumForMac can actually automate anything which is available to the Accessibility API. (NB: Third-party keyboards may not work with this functionality.)

     AXPath strings generated by AppiumForMac to be pretty long. Make sure to organize your test so common parts of the string can be reused. Removed many of the predicates since they were too-specific and not necessary.

     Another tool which can help with AXPath strings is the Accessiblity Inspector. This tool will show the hierarchy of accessibility elements, allow you to click on an element to inspect it, and view properties on elements.

 As a last resort, you can try to dump the entire view hierarchy by calling driver.getSource(). This works on simple apps, but hung indefinitely on the Activity Monitor app, most likely because the UI is constantly updating.

Below is the sample Test for MAC application automation,

import io.appium.java_client.AppiumDriver;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;public class Automate_Mac {private AppiumDriver driver;

@Before
public void setUp() throws IOException {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(“platformName”“Mac”);
caps.setCapability(“deviceName”“Mac”);
caps.setCapability(“app”“Activity Monitor”);

caps.setCapability(“newCommandTimeout”300);
driver = new AppiumDriver(new URL(http://localhost:4723/wd/hub), caps);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}


@Test
public void testActivityMonitor() {
String baseAXPath = “/AXApplication[@AXTitle=’Activity Monitor’]/AXWindow”;
String tabSelectorTemplate = baseAXPath + “/AXToolbar/AXGroup/AXRadioGroup/AXRadioButton[@AXTitle=’%s’]”;
driver.findElementByXPath(String.format(tabSelectorTemplate,“Memory”)).click();
driver.findElementByXPath(String.format(tabSelectorTemplate,“Energy”)).click();
driver.findElementByXPath(String.format(tabSelectorTemplate,“Disk”)).click();
driver.findElementByXPath(String.format(tabSelectorTemplate,“Network”)).click();
driver.findElementByXPath(String.format(tabSelectorTemplate,“CPU”)).click();
WebElement searchField = driver.findElementByXPath(baseAXPath +“/AXToolbar/AXGroup/AXTextField[@AXSubrole=’AXSearchField’]”);
searchField.sendKeys(“Activity Monitor”);WebElement firstRow = driver.findElementByXPath(baseAXPath +“/AXScrollArea/AXOutline/AXRow[0]/AXStaticText”);Assert.assertEquals(” Activity Monitor”, firstRow.getText());
}
}

     Try to use above concept of MAC Desktop app automation from your end and enjoy automation.

Reference: Appium Pro

make it perfect !

Speed Up Android Appium Test Automation

android-automation

      There are three special capabilities available in Appium for speeding up Android test initialization (available in the latest Appium version). Also using the appPackage and appActivity desired capabilities instead of the app capability helps for speeding up Android test automation.

  1. skipDeviceInitialization
  2. skipServerInstallation
  3. ignoreUnimportantViews

     skipDeviceInitialization is available for all Android platforms, this desired capability can be passed with the boolean value true to skip installing the io.appium.settings app on the device. This special app is installed by the Appium Android Driver at the beginning of each test and is used to manage specific settings on the device, such as:

  • Wifi/data settings
  • Disabling animation
  • Setting a locale
  • IME settings

Without the io.appium.settings app, the Appium Android driver cannot automate these functions, but if the device previously had this app installed by Appium, it doesn’t need to install it again. If you know that your device is already in the proper state then you can set skipDeviceInitialization to true and skip the time it takes to reinstall it. Appium already checks if the settings app is already installed on the device, but with this capability enabled it even skips the check to see if the app is installed.

     skipServerInstallation desired capability only applies when using the UiAutomator2 automation method. The way the UIAutomator2 driver works, it installs a special server onto the device, which listens to test commands from Appium and executes them. By default, Appium installs this server onto the device at the beginning of every test session. If the value of skipServerInstallation is set to true, you can skip the time it takes to install this server. Of course, without the server on the device Appium can’t automate it, but if you know that the server was installed during a previous test run you can safely skip this step.

   ignoreUnimportantViews desired capability is not new, but it deserves to be mentioned as another way to potentially speed up Android automation tests, especially if your tests focus on finding many elements using XPath locators. Set this to true to speed up Appium’s ability to find elements in Android apps.

     Another major time-saver when it comes to Android tests is using the appPackage and appActivity desired capabilities instead of the app capability. We need to tell Appium which app to test. Usually we use the app capability, which can be a path to a .apk, .apks, or .zip file stored on your computer’s filesystem or stored on a public website. If the app under test is known to already be installed on the device (most likely from a previous test run), the app package name and main activity can be passed instead (using appPackage and appActivity desired capabilities). Skipping the time to download a large file or install it on the Android operating system leads to big savings.

Below is the sample code which explain how can we use it in your automation script:

DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(“platformName”, “Android”);
caps.setCapability(“deviceName”, “Android Emulator”);
caps.setCapability(“automationName”, “UiAutomator2”);
// App is already installed on device, so can be launched by Package name and Activity
caps.setCapability(“appPackage”, “io.cloudgrey.the_app”);
caps.setCapability(“appActivity”, “io.cloudgrey.the_app.MainActivity”);
// Skip the installation of io.appium.settings app and the UIAutomator 2 server.
caps.setCapability(“skipDeviceInitialization”, true);
caps.setCapability(“skipServerInstallation”, true);
caps.setCapability(“ignoreUnimportantViews”, true);
driver = new AppiumDriver(new URL(“http://localhost:4723/wd/hub”), caps);

Try to practice the above mentioned methods in your Android Automation and feel the difference in execution speed.

Reference: Appium Pro

make it perfect !

Send Automation Reports as Mail Report

screen-shot-2012-11-13-at-11-25-44-pm

    Automation test reports are one of the important deliverable of Automation executions. Getting those automation reports in the mail automatically is the another important concept. Here, I would like to share the information about how to send your automation reports as mail report with attachment while automation of your application with Java or C# languages.

Send automation test reports with Java language:

Prerequisites:

        Need to add javax.mail dependency in pom.xml of your automation project (if it is a Maven project. Otherwise need to add javax.mail jar in your Java Build Path of your Java project). Following is the javax.mail dependency,

<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>

Following sendMailReport() method helps to send test automation reports with attachment,

public static void sendMailReport() throws AddressException, MessagingException {
String subject = “”, message = “”, maillist = “”, EMAIL_REPORT_FOLDER = “”;
subject = “Automation Test Report_”;
message = “Please find the attached report to get details.”;
maillist = “mail_lists_of_recipients”;
EMAIL_REPORT_FOLDER = “path_to_automation_report_folder”;
Properties properties = new Properties();
properties.put(“mail.smtp.host”, “smtp.gmail.com”);
properties.put(“mail.smtp.port”, “587”);
properties.put(“mail.smtp.auth”, “true”);
properties.put(“mail.smtp.starttls.enable”, “true”);
final String userName;
final String password;
userName = “sender_mail_address”;
password = “sender_mail_account_password”;
properties.put(“mail.user”, userName);
properties.put(“mail.password”, password);

Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
};
Session session = Session.getInstance(properties, auth);
DateFormat dff = new SimpleDateFormat(“EEE MMM dd, yyyy HH:mm:ss z”);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(userName));
msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(maillist));
msg.setSubject(subject + ” – ” + dff.format(new Date()).toString());
msg.setSentDate(new Date());

// creates message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(message, “text/html”);

// creates multi-part
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);

// adds attachments
List<String> filesList = new ArrayList<String>();
File[] files = new File(System.getProperty(“user.dir”) + EMAIL_REPORT_FOLDER).listFiles();
for (File file : files) {
if (file.isFile()) {
filesList.add(System.getProperty(“user.dir”) + EMAIL_REPORT_FOLDER + “/” + file.getName());
}
}
if (filesList != null && filesList.size() > 0) {
for (String filePath : filesList) {
MimeBodyPart attachPart = new MimeBodyPart();
try {
attachPart.attachFile(filePath);
} catch (IOException ex) {
ex.printStackTrace();
}
multipart.addBodyPart(attachPart);
}
}
// sets the multi-part as e-mail’s content
msg.setContent(multipart);
// sends the e-mail
Transport.send(msg);
}

Send automation test reports with C# language:

       The System.Net.Mail namespace contains classes used to send electronic mail to a Simple Mail Transfer Protocol (SMTP) server for delivery. Following Send_Report_In_Mail() method helps to send test automation reports with attachment,

public void Send_Report_In_Mail()
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient(“smtp.gmail.com”);
mail.From = new MailAddress(“sender_mail_address”);
mail.To.Add(“mail_lists_of_recipients”);

StringBuilder TimeAndDate = new StringBuilder(DateTime.Now.ToString());
TimeAndDate.Replace(“/”, “_”);
TimeAndDate.Replace(“:”, “_”);

mail.Subject = “Automation Test Report_”+ TimeAndDate;

mail.Body = “Please find the attached report to get details.”;

string actualPath = AppDomain.CurrentDomain.BaseDirectory.Replace(“\\bin\\Debug”, “\\Test_Execution_Reports”); //Reports should stored in Test_Execution_Reports folder

var mostRecentlyModified = Directory.GetFiles(actualPath, “*.html”)
.Select(f => new FileInfo(f))
.OrderByDescending(fi => fi.LastWriteTime)
.First()
.FullName;

Attachment attachment;
attachment = new Attachment(mostRecentlyModified);
mail.Attachments.Add(attachment);

SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential(“sender_mail_address”, “sender_mail_account_password”);
SmtpServer.EnableSsl = true;

SmtpServer.Send(mail);

}

     You can use those method in @AfterSuite if you are using TestNG. In case of NUnit(C#), you can use those method in [OneTimeTearDown]. Try to use above code snippet in your automation scripts to send your automation test report as mail report automatically.

make it perfect !

Automating Voice Commands With Siri

iphone-6s-siri

     It’s very common with modern mobile devices to rely on virtual “assistants” to get tasks done, whether in a hands-free situation utilizing voice commands, or just to save the trouble of tapping out search queries. On iOS these interactions take place through the Siri interface.

Hey Siri

     How on earth would you test this aspect of your app’s behavior? Ideally you’d be able to have a recording of the particular voice command or phrase used to trigger your app’s Siri integration, which you could then somehow apply to the simulator or device under test. This is not currently possible, outside of rigging up some speakers!

     Fortunately, Appium has recently added a command (as of Appium 1.10.0), that lets you specify the text you want Siri to parse, as if it had been spoken by a person.

The command itself is accessible via the executeScript “mobile” interface:

HashMap<String, String> args = new HashMap<>();
args.put(“text”, “Hey Siri, what’s happening?”);
driver.executeScript(“mobile: siriCommand”, args);

     Essentially, we construct an options hash with our desired text string, and pass it to the siriCommand “mobile” method. We can run this command at any point in our automation, and it will take care of getting to the Siri prompt for us as well (we don’t need to long-hold the home button).

     At this point we can use the typical native automation methods to verify Siri’s response on the screen, tap on action items, etc…

     That’s basically it! There’s not much to it. So let’s have a look at a full example that asks Siri a math question (What’s two plus two?) and verifies the result (notice how the result text shows up as accessibility IDs, which found by looking at the page source).

@Test
public void testSiriTalk() {
HashMap<String, String> args = new HashMap<>();
args.put(“text”, “What’s two plus two?”);
driver.executeScript(“mobile: siriCommand“, args);
wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId(“2 + 2 =”)));
wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId(“4”)));}

     You have to use java-client version as 6.1.0 and Appium server version as 1.10.0. Try to use above sample test case to see what exactly automating voice command with Siri.

Reference: Appium Pro

make it perfect !